I'm new to learning java. I have been working how i can do it for 2 days. I will be mad. Please help me
I want that when my function run, all activity must wait until my function is finished.
an example
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
webView2 = (WebView) findViewById(R.id.webView);
Log.v("htmlg","oncreate started");
main_command();
/*
*
* main_command(), When this command run application must wait in here.
*
* */
Log.v("htmlg", "oncreate finished");
}
public static int finished = 0;
public void main_command(){
/*
*
* There is some webview actions in here. it takes about 5 minutes.
*
* When webview operations are finished.
* I call javascript command javascript:window.HTMLOUT.ok();
* I want everything wait until webview operations are finished and javascript command runned.
*
* */
}
But I could not do it with no way. When main_command() runned, Log.v() function will run after it immediately. but main_command() is still running and it is not finished. when it finished a javascript command will call a function inside android. then process will be finished and application can continue to work where it was.
Now, I'm telling my experiences.
I tried to write webview codes inside Asynctask but I could not use webview inside asynctask.
i put webview inside rununithread() inside asynctask, i could not do again.
i tried to put main_command() inside CountdownTimer but "oncreate finished" line runned before CountdownTimer finished.
Now i feel helpless. I dont know java or android programming so much. I am php programmer. I try to do webview application. I dont understand java structure so much. If you can do , can you write correct example working code ? Because I dont understand all examples. I looked and read everything maybe there was solution but I could not understand it. I need your help.
Thanks
You don't want to block the main thread, otherwise the android system will show "Application not responding" error. And your users will most probably choose to kill the app.
From what I understand, you want your application to resume when you call it through a javascript command. This is how you can proceed:
Make a function postMainCommand(). In this method, write everything that needs to be executed after that javascript command call. I mean the ones like:
Log.v("htmlg", "oncreate finished");
Call this method after your web-work is complete.
Till your job is in progress, you can show a non-cancelable progress-dialog with some text like "Please wait...". Or, if you can keep track of the progress, you can keep updating the message:
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Please wait...");
dialog.setCancelable(false);
dialog.show();
Non-cancellable because you don't want the user to interact with the app in-between, right?
When your webview job is over, call dialog.cancel();
Related
I have created a startup activity from where I am calling another activity which has a view pager and shows some introductory pages.
This app was taking time to load so I thought to display a progress dialog till the activity loads, but that progress dialog also appears few seconds later.
startup activity:
public class StartUpActivity extends AppCompatActivity {
boolean isUserFirstTime, login;
public static String PREF_USER_FIRST_TIME;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isUserFirstTime = Boolean.valueOf(Utils.readSharedSetting(StartUpActivity.this, PREF_USER_FIRST_TIME, "true"));
Intent introIntent = new Intent(StartUpActivity.this, SlidingActivity.class);
introIntent.putExtra(PREF_USER_FIRST_TIME, isUserFirstTime);
ProgressDialog dialog = new ProgressDialog(StartUpActivity.this);
dialog.setMessage("Welcome to Mea Vita, please wait till the app loads.");
dialog.setCancelable(false);
dialog.setInverseBackgroundForced(false);
dialog.show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Here you can send the extras.
startActivity(new Intent(StartUpActivity.this,SlidingActivity.class));
// close this activity
finish();
}
}, 4000);
}
}
This doesn't happen every time,only sometimes. What can be the possible reason for this? how can I stop this?
Any solution? Thank you..
There is a strange issue with newly released Android Studio 2.0 (same issue in 2.1) first time of launching application take longer than usual (e.g. 2, 3 seconds or sometimes screen blinks or goes black) this issue happens only in debug mode and not effect your released APK.
A temporary solution to fix this is disabling instant run:
Settings → Build, Execution, Deployment → Instant Run and uncheck Enable Instant Run
First of all, make as rule to make all data loading in async tasks, you must check activity that you want to start where you load data.
The problem is in your second activity.
oncreate method should be used only to make findviews or start async tasks, don't load any in oncreate or in onstart or in onresume.
Probably you are loading high res images in sliding layout or you loading data in it.
There is another way, load all data in async task on first activity, then with ready data start second activity with already data loaded.
There are a few things that can load slowly.
Android need to read your code from storage and load the classes into ram.
I assume Utils.readSharedSetting(StartUpActivity.this, PREF_USER_FIRST_TIME, "true") reads from preferences. That's a file that you're reading from synchronously.
Actually launching the dialog takes a very small amount of time.
I'd suggest showing your loading inside the activity itself to minimize the work needed to render it.
Also, you can store PREF_USER_FIRST_TIME as a boolean instead of a String.
I have a class, that executes some command in background. Class method is executed asynchronously (by using AsyncTask) and when command finishes, it posts event with command result. Then, new activity is started. To do this, I added inside OnCreate method to MainActitity:
ssh = new SshSupport();
ssh.Connect();
ssh.ExecuteCommand(commandType);
//..................................
ssh.eventHandler = new ISshEvents()
{
#Override
public void SshCommandExecuted(SshCommandsEnum commandType, String result)
{
if (progressDialogExecuting.isShowing()) progressDialogExecuting.dismiss();
Intent intent = new Intent(MainActivity.this, ResultListActivity.class);
intent.putExtra("result", result);
intent.putExtra("commandType", commandType);
startActivity(intent);
}
So it works as should. My commands starts in background and when finished, my event fires and displays new activity with results (all results are received via getIntent().getExtras() and then formatted to be displayed as should).
Problem: on result activity I have "Refresh" button. When pressed, all data should be refreshed. So I need to execute ssh.ExecuteCommand(commandType); again to get refreshed data. Note that I don't want to open new ssh connection for this. Instead, I want to use already opened connection and simply execute my command again.
So I made my 'ssh' static and I used MainActivity.ssh.ExecuteCommand(commandType); on refresh button press. It works, but obviously, it causes to create second instance of ResultListActivity, instead of refreshing data on existing one.
I can even avoid to creating result activity again by checking if it's already exists (for example by adding 'active' boolean static variable to it). However, it won't help me because I still have no any possibility to refresh data inside my existing activity.
So, how can I do it?
No responses, so I'm answering to my own question. My solution was:
- Change my activity launchMode to singleTop
- Override method onNewIntent
In this case each time I start this activity: if activity already exists it won't be created again. Instead, onNewIntent method will be called.
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
http://developer.android.com/reference/android/app/Activity.html#onNewIntent%28android.content.Intent%29
However, I'm not sure if approach like this is good. How do you think?
I'm begining with Android development. I have an asynchronous operation, but my intention is wait the operation is completed, and after that, continue the execution of my program.
I have used AsyncTask, and all its methods, but I got error, because on the onPreExecute method I want to show another Activity, so I guess I can't show another Activity. That's the reason I want to wait to complete the asynchronous operation.
Greetings
1st edit:
I've used AsyncTask(onPreExecute, doInBa..., onPost... ), but none method works. I understand how it works the AsyncTask class, but I want stop the execution when I invoke one asynchronous thirdparty method, because in the listener that needs, I change the value of a String variable X, and after invoke my method, that uses the thirdparty method, I use the variable X. I got an exeption because the variable hasn't updated.
Please, read and follow example of AsynTask. You need to override onPostExecute
Not entirley sure what the question is but AsynTask has a method that you can call after everything has completed. A good practice is to have a dialog or a spinner showing that work is happening then dismiss it.
class loadingTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
//Do work
}
protected void onPostExecute(String s) {
ShowProgress.dismiss();
Intent myIntent = new Intent(this, PostExAct.class);
startActivity(myIntent);
}
}
In your on create:
ShowProgress = ProgressDialog.show(MainActivity.this, "",
"Loading. Please wait...", true);
new loadingTask().execute("params here");
This will show a loading dialog and while the work is being done then will be dismissed when the work is finished.
I am trying to write some Activity tests for an app, and one particular scenario that I want to test is that when I click a certain button, the Activity view updates accordingly. However, clicking the button causes a somewhat long running asynchronous task to start and only after that task is completed does the view change.
How can I test this? I'm currently trying to use the ActivityInstrumentationTestCase2 class to accomplish this, but am having trouble figuring out how to have the test 'wait' until the asynchronous part of the button click task is complete and the view updates.
The most common and simplest solution is to use Thread.sleep():
public void testFoo() {
TextView textView = (TextView) myActivity.findViewById(com.company.app.R.id.text);
assertEquals("text should be empty", "", textView.getText());
// simulate a button click, which start an AsyncTask and update TextView when done.
final Button button = (Button) myActivity.findViewById(com.company.app.R.id.refresh);
myActivity.runOnUiThread(new Runnable() {
public void run() {
button.performClick();
}
});
// assume AsyncTask will be finished in 6 seconds.
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
assertEquals("text should be refreshed", "refreshed", textView.getText());
}
Hope this helps.
If you're using Eclipse, you could use the debugger by setting a breakpoint in the code that updates the view. You could also set some breakpoints in the long running task to watch and ensure that all your code is executing.
An alternative, write some log or console outputs in your long-running task and the view updater code, so you can see the progress without interrupting the thread by a debugger.
As a piece of advise, if its a long-running process, you should be showing a progress bar of some description to the user, so they aren't stuck there thinking "Is something happening?". If you use a progress bar with a maximum value, you can update it in your long-running task as it is running, so the user can see the activity going from 10% to 20%... etc.
Sorry if you were expecting some kind of jUnit-specific answer.
I ended up solving this by using the Robotium library's Solo.waitForText method that takes a string and timeout period and blocks until either the expected text appears or the timeout occurs. Great UI testing library.
I have a really weird problem, which I am unable to debug so far...
Thing is...my app needs to download something to work. So in the beginning of the onCreate() method, I check if that something is already downloaded. If not, I pop a dialog up asking the user to download it.
if (!isInstalled) {
showDialog(DIALOG_INSTALL);
} else {
start();
}
Where start() method performs some other action. Now, that showDialog calls this:
builder = new AlertDialog.Builder(MyApp.this);
builder.setMessage("Would you like to install...")
.setCancelable(false)
.setPositiveButton("Install", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
aManager.install(MyApp.this);
}
});
dialog = builder.create();
return dialog;
My dialog is shown and I am clicking, so aManager.install() is called. I am passing the context because that aManager.install() pops up a ProgressDialog to show downloading progress and spawns a new thread in which everything is downloaded. So obviously before creating my dialog I make a Handler to receive the response from that aManager.install(). And the response MAY vary, because for example the internet connection isn't available (Exception raised and catched and listener called with different code).
Now, when that happens (Exception) I would like to call another dialog saying "something went wrong, would you like to retry?"...so another call to showDialog(DIALOG_REINSTALL) (this time with another code).
Thing is...the showDialog() gets called (I can verify this by logging) but the dialogs doesn't show up. Instead my application JUST HANGS!?!?!?
Does someone have a clue why it's doing this???? No exception raised, absolutely nothing from logcat, I can't tell WHERE it's hanging...just see that the method is called and the dialog should be displayed...
Thank you very much!!
Looks like you have a deadlock. I would put the download code on the separate thread e.g. use AsyncTask. In task.onPreExecute() you can dismiss 1st dialog and pop-up your progress dialog which you update by overwriting task.onProgressUpdate()
Use .show() instead of .create().