I have an activity, and a buttonClick where I call a Thread that will POST some JSON to a PHP file. I want the activity to get Closed after the thread ends. How can I do that?
This is my click event:
Button bsave = (Button) findViewById(R.id.button3);
View.OnClickListener eventHandlerx = new View.OnClickListener() {
#Override
public void onClick(View arg0) {
sendJson( urlx, jsonarray);
}
...
And this is my Thread:
private void sendJson(final String urlx, final JSONArray jsonarray) {
Thread t = new Thread() {
public void run() {
Looper.prepare();
...}
...}
}
Where can I call finish() in order to close my activity?
Thank you
You can call finish() from anywhere within the UI thread. You can execute code from within the UI thread by using an AysncTask's onPostExecute (replace your Thread with it) or by starting a Runnable using the Activity's runOnUiThread.
Hope it will help
class SendJson extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//here you can call functionality
}
#Override
protected void onPostExecute(String result) {
//here you can call finish
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Here's an example using Handler since you just want to close the activity:
new Handler().post(new Runnable() {
#Override
public void run() {
//do your stuff here
MyActivity.this.finish();
}
});
But as #dst mentioned, you should use AsyncTask whenever possible.
I did tests
- you can startActivity from non-ui Thread
- you can finish Activity from non-ui Thread
Look at the ACRA project - nice exception handling. In ReportExecutor in line 251 (https://github.com/ACRA/acra/blob/master/src/main/java/org/acra/builder/ReportExecutor.java#L251) activity is started in new thread.
I was too surprised why it is working :)
Related
Right now I'm facing a problem which I cannot solve, There's a thread which I need to fill two arrays with specific data, and then use these two arrays later, however, my main thread does not wait for the thread to finish and I don't know why!!
Here is my code
private void loadingData(){
Thread myThread=new Thread(new Runnable() {
#Override
public void run() {
getNationalities();
getReligions();
}
});
myThread.start();
try {
myThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
loadingIcon.show();
while(myThread.isAlive()){}
//Here I'm using the two filled arrays
nationalitySpinner();
religionSpinner();
loadingIcon.hide();
}
You can't run asynchronous Networking or time-consuming operation in the in main thread it will freeze the UI.
Try to use AsyncTask, in OnPostExecute of AsyncTask you can update in UI
Example :
private void loadingData(){
new MyTask().execute();
}
class MyTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
loadingIcon.show();
}
#Override
protected Void doInBackground(Void... voids) {
getNationalities();
getReligions();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
nationalitySpinner();
religionSpinner();
loadingIcon.hide();
}
}
For more info refer Processes and threads, AsyncTask
I have a log-in-Thread and while it is running i want to show up kind of a "loading-circle". So how can i recognize when the thread ends and react to it?
loadingcicle.setVisibility(View.VISIBLE);
Thread t = new Thread(new Einloggen());
t.start();
//and at the end
loadingcicle.setVisibility(View.GONE);
You probably want to use the asynctask pattern.
http://developer.android.com/reference/android/os/AsyncTask.html
something like
new AsyncTask<Void, Void, Void>() {
protected void onPreExecute() {
showProgress(true);
}
protected void void onPostExecute(Void result) {
hidProgress(true);
}
protected Void doInBackground(Void...voids) {
doMyBackgroundStuff();
}
}.executeOnExexutor(AsyncTask.THREAD_POOL_EXECUTOR);
of course you should be aware of activity lifecycle events and check that you are at least started or resumed before updating the ui.
You could instantiate a Handler object on your activity and pass it to your Einloggen class. So with this handler you can call Handler.post() to execute commands on UIThread.
Look at this reference: http://developer.android.com/reference/android/os/Handler.html
final android.os.Handler mHandler = new android.os.Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
switch (msg.what){
case 1:
//
Toast.makeText(context,"Responded !!!",Toast.LENGTH_LONG).show();
break;
}
return false;
}
});
new Thread(new Runnable() {
#Override
public void run() {
//do whatever you want here
mHandler.sendEmptyMessage(1);
}
}).start();
I have a specific case where I want to run an AsyncTask's doInBackground on UI Thread. How can I do that?
You definitively could, but as #Devrath said, it is pointless. AsyncTask are used for background operation.
Here is a sample that uses the runOnUiThread method:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// WORK on UI thread here
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
I ended up doing the following:
Got all the code from doInBackground and moved it to a method.
In doInBackground I make a call only to this method.
In the cases where I need the asynctask to be executed normally, I call LongOperation().execute()
In the cases where I need the asynctask to be ran on the UI thread, I dont call it but I call the method instead.
Try this
public void commentBuilder() {
new Thread(new Runnable() {
#Override
public void run() {
//Your code
}
}).start();
}
Also, see this for more detail https://stackoverflow.com/a/14038370
As far i know ..... You cannot !
AsyncTask are designed to perform background task which takes
longer time to perform
So they have to be performed in a seperate thread different from the
mainthread
Mainthread takes care of all the UI for your app
If you want ot update a UI while performing a background operation::
Just use onProgressUpdate method of the AsyncTask to update the
UI during the background operation
else use onPre method to update UI before the beckground call is
made
Else finally use onPost method to update after rte async task
completes doInBackground
{SAMPLE}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
I want to show the progress dialog while loading the images in grid view.
The problem i'm facing was the current thread and Progress Dialog thread running simultaniously.
public String Method1(){
String output="";
final ProgressDialog aProgDialogL = ProgressDialog.show(this, "", "Loading...");
Thread thread = new Thread() {
public void run () {
//My codes
aHandlerL.post(new Runnable() {
#Override
public void run() {
//Post Runnable codes
aProgDialogL.dismiss();
}
});
}
};
thread.start();
/*
*
*
* OTHER CODES
*
*
*/
return output;
}
In the above example I need to run the code inside Progress Dialog Thread. After it finish executing i need to run my "OTHER CODES". How to do it?
.
I tried using Async task. Before async task completes method1 gets extcuted and reurning the string.
public String Method1(){
String result="";
new GetImages().execute();
return result;
}
public class GetData extends AsyncTask<Void, Void, Integer>{
#Override
protected void onPreExecute() {
aProgDialogL = ProgressDialog.show(Main.this, "", "Loading...");
}
#Override
protected Integer doInBackground(Void... params) {
//Progress Dialig Code
return null;
}
#Override
protected void onPostExecute(Integer result) {
aProgDialogL.dismiss();
//OTHER CODES
super.onPostExecute(result);
}
}
You can use Async task. http://developer.android.com/reference/android/os/AsyncTask.html. There is a good tutorial here. http://www.vogella.com/articles/AndroidPerformance/article.html.Also have a look at this link
http://developer.android.com/guide/components/processes-and-threads.html. Use asynctask modify it according to your needs.
doInBackground()- For long running operations. Don't update ui here.
onPreExecute()- update ui before running the operatio nin background.
onPostExecute()- update ui after running the operation.
I would suggest you to take somewhat different approach.
Dont involve any threads in Method1() function.Rather your Method1() function should be run under separate thread.
Below snippet will help you.
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((Button) findViewById(R.id.btnPopup))
.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new Thread() {
public void run() {
String answer = Method1();
runOnUiThread(new Runnable() {
#Override
public void run() {
// Here you will write the code which is
// to be executed on main thread.
}
});
};
}.start();
}
});
}
public String Method1() {
// Write code
return "result";
}
}
Instead of that : What about use Timer After specific Time Stop Your thread and and write your code you want after stop statement Like that :
Timer timer=new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
thread.stop;
// Other code }
}, Time You want );
I am building a project in which i use async task to show progress bar.
I am using get() method to wait the main thread so we can do the other task before .
but progress bar is showing after completion of doInBackground thered.
I Want to show the loading bar when the loading starts.
It will dismiss when onPostExecute calls.
public class TempConverterActivity extends Activity {
pojo p;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b= (Button) findViewById(R.id.btn);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showResult();
}
});
}
private void showResult() {
try {
new LoadData().execute().get();
} catch (Exception e) {
Log.e("async brix--", e.getMessage());
}
runned();
}
private void runned() {
ArrayList<String> al = p.getData();
for (String str : al){
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
}
}
private class LoadData extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(TempConverterActivity.this);
protected void onPreExecute() {
dialog.setMessage("Loading data...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
protected void onPostExecute(final Void unused) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
#Override
protected Void doInBackground(Void... params) {
p = new pojo();
new SoapParser(p);
return null;
}
}}
Please help . Thanks in advance.
You can try following code,
progDailog = ProgressDialog.show(loginAct,"Process ", "please wait....",true,true);
new Thread ( new Runnable()
{
public void run()
{
// your code goes here
}
}).start();
Handler progressHandler = new Handler()
{
public void handleMessage(Message msg1)
{
progDailog.dismiss();
}
}
Edited: In my previous answer I suggested using a Handler; however, AsyncTask eliminates the need to do this which I didn't spot.
Why do you feel the need to call AsyncTask.get()? This is a blocking call, and you call this from the UI thread, thus it is ultimately a race condition as to whether it or onPreExecute() is run first.
I see no reason why you should call get() in this context. You want to call runned() after the AsyncTask completes, but you could do this by launching a new thread from onPostExecute(). Alternatively you could do as you do now, using get(), but call that from a new thread instead of the UI thread.