I want to update the UI during an intensive task. I've got a separate thread where the intensive method runs but I can't update the UI...
This is the structure of my code:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
updateUI();
Thread t = new Thread(){
#Override
public void run(){
runIntensiveMethod();
}
}
t.start();
}
});
If I comment runIntensiveMethod(); the animation runs perfectly fine. However, it seems as though the UI queue is delayed until the method is run.
How can I post an animation and run the method while the animation runs?
Everything I've tried halts the UI until the method has been executed.
You should set a priority for that thread:
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
Also check here
Just call runOnUiThread when you want to refresh from your runIntensiveMethod()
runOnUiThread(new Runnable()
{
#Override
public void run()
{
updateUI();
}
});
Change your code to this, this should work.
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Thread t = new Thread(){
#Override
public void run(){
runIntensiveMethod();
runOnUiThread(new Runnable() {
public void run() {
updateUI();
}
}
}
t.start();
}
});
Related
There's thread order method like thread.join()
But how to wait thread start point until not thread method done
I made button click listener. In there takePicture function need to start and finish before start Thread.
But when I debug, takePicture and Thread start almost simultaneously.
How can I prevent this?
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
takePicture();
new Thread(new Runnable() {
#Override
public void run() {
send();
}
}).start();
}
});
++++++
make takePicture to thread and do join() before starting below thread not working
this also below thread done first...
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
try {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
takePicture();
}
});
thread1.start();
thread1.join();
new Thread(new Runnable() {
#Override
public void run() {
Log.d("point", "3");
send(image_byte);
}
}).start();
}catch (InterruptedException e){
e.printStackTrace();
}
}
});
I want complete code to disable a Button for some time for example 2 minutes in Android Studio. Thank you for help.
protected void onclick(View v){
bwasta = (Button) findViewById(R.id.btDes);
new CountDownTimer(10000, 10) { //Set Timer for 10 seconds
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
bwasta.setEnabled(true);
bwasta.setEnabled(false);
}
}.start();
This might help you out.
Button bwasta = (Button) findViewById(R.id.btDes);
bwasta.setEnabled(false);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2*
60*
1000);//min secs millisecs
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
YourActivityName.this.runOnUiThread(new Runnable() {
#Override
public void run() {
bwasta.setEnabled(true);
}
});
}
}).start();
DO NOT RELY ON Thread.sleep()
Actually, there is already a Question and an Answer on SO regarding the inaccuracy of Thread.sleep()(as per the OP's experience) here.
The answer then favors the accuracy of a ScheduledThreadPoolExecutor using the schedule() method.
Do the following:
Button bwasta = (Button) findViewById(R.id.btDes);
bwasta.setEnabled(false);
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.schedule(new new Runnable() {
#Override
public void run() {
YourActivityName.this.runOnUiThread(new Runnable() {
#Override
public void run() {
bwasta.setEnabled(true);
}
});
}
}, 2, TimeUnit.MINUTES);
You can use mHandler.postDelayed(mRunnable, mTime) function to achieve this
Button bwasta = (Button) findViewById(R.id.btDes);
bwasta.setEnabled(false);
bwasta.postDelayed(new Runnable() {
public void run() {
bwasta.setEnabled(true);
}
}, 2*60*1000);
I have to update the list after optimizing the running apps ....
m_optimizeBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
launchProgressRing(OptimizationActivity.this);
listAdaptor.notifyDataSetChanged();
}
});
}
Killing the running process in a seprate thread....
public void launchProgressRing(Context ctx){
final ProgressDialog opt_proDialog=new ProgressDialog(ctx);
opt_proDialog.setTitle("Please wait...");
opt_proDialog.setMessage("Optimizing power draining apps...");
opt_proDialog.setIndeterminate(true);
opt_proDialog.show();
opt_proDialog.setCancelable(false);
new Thread(new Runnable()
{
#Override
public void run()
{
//TODO: optimize apps
m_cPowerDrainingApps.killBgRunningProcesses(runningAppsList);
try
{
Thread.sleep(1500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
runOnUiThread(new Runnable()
{
#Override
public void run()
{
opt_proDialog.dismiss();
}
});
}
}).start();
}
listAdaptor.notifyDataSetChanged() is not working ,don't know why ???
What I suggest is to use AsyncTask to do the job. AsyncTask has two good methods for you:
doInBackground: which you can put most of the background tasks in there
onPostExecute : which you can put the logic of what needs to be done when the background task has finished its job.
So your code should look like this:
public class BackgroundTask extends AsyncTask<Void,Void,Void>{
private ListAdapter mAdapter;
public BackgroundTask(ListAdapter adapter)
{
mAdapter = adapter
}
public Void doInBackground (Void... params)
{
//define m_cPowerDrainingApps somewhere
m_cPowerDrainingApps.killBgRunningProcesses(runningAppsList);
try
{
Thread.sleep(1500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
public Void onPostExecute (Void... params)
{
//do your UI things
mAdapter.notifyDataSetChanged();
}
}
and then run this with:
new BackgroundTask(listAdapter).execute()
Use a Handler and its postDelayed method to invalidate the list's adapter as follows:
final Handler handler = new Handler()
handler.postDelayed( new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
handler.postDelayed( this, 60 * 1000 );
}
}, 60 * 1000 );
You must only update UI in the main (UI) thread.
right now i'm doing
public void someStuff(){
new Thread(new Runnable() {
#Override
public void run() {
//doing long task
doOtherStuff();
}
}).start();
}
public void doOtherStuff(){
doEvenMoreStuff();
}
but the problem is that it executes doOtherStuff in the same thread and It needs to be executed in the UI Thread. how can I accomplish this?
I am only using the thread because otherwise the app freezes. I just need doOtherStuff to wait for the thread to finish.
Try this:
this.runOnUiThread(new Runnable() {
#Override
public void run() {
//do something
}
});
this is your activity.
Use handler :
public void doOtherStuff(){
new Handler(context.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// Executes on UI thread
doEvenMoreStuff();
}
});
}
where context might be your Activity
Not sure if best practice but you can Try this:
public void someStuff(){
new Thread(new Runnable() {
#Override
public void run() {
YourActivityClassName.this.runOnUiThread(new Runnable() {
#Override
public void run() {
//doing long task
doOtherStuff();
}
});
}
}).start();
An alternative way of using Handler which other answers suggested is AsyncTask:
It has two methods which can be useful in your case:
doInBackground: which runs in the background thread so your UI won't freeze
onPostExecute: which runs on UI thread after doInBackground finishes. A generic class may look like:
private class MyTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... input) {
//do background processes on input and send response to onPostExecute
return response;
}
#Override
protected void onPostExecute(String result) {
//update UIs based on the result from doInBackground
}
}
and you can execute the task by:
new MyTask(inputs).execute()
I'm new to android and have been doing some reading about worker threads and not blocking the UI thread. I'm playing around with a simple timer app that starts a thread that updates a textview every second when the activity is created. So my question is, these days what is the best way to do this. Both of the two examples below work but is there a better (more efficient/ more Android) way?
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
seconds++;
runOnUiThread(new Runnable() {
#Override
public void run() {
secondsTextView.setText(seconds);
}
});
handler.postDelayed(this, 1000);
}
}, 1000);
or
new Thread(){
#Override
public void run(){
try{
while(!isInterrupted()){
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
seconds++;
secondsTextView.setText(seconds);
}
});
}
}catch(Exception e){
Log.e("Activity1", e.toString());
}
}
}.start();
The more efficient way is:
timeOnTextView.postDelayed(new Runnable() {
#Override
public void run() {
seconds++;
timeOnTextView.postDelayed(this, 1000);
}
}, 1000);
The run() of the Runnable passed to postDelayed() is invoked on the main application thread, so you do not need to use runOnUiThread().
Since postDelayed() is implemented on View, you do not need a Handler.