I am trying to show progress dialog and update it inside runOnUiThread
but the progress bar never shown. when I replace the runOnUiThread with "new Thread" it work fine. But I want it to work with runOnUiThread
here is my code , I have deleted unnecessary codes
public class test extends Activity {
private ProgressDialog progress;
Handler progressBarHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
testing();
}
public void testing() {
progress=new ProgressDialog(this);
progress.setMessage("Saving Progress");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setProgress(0);
progress.setMax(100);
progress.setCancelable(false);
progress.show();
runOnUiThread(new Runnable() {
#Override
public void run() {
//do some work
for (int i =0; i<100;i++){
//some work
progressBarHandler.post(new Runnable() {
#Override
public void run() {
progress.setProgress(finalCount);
}
});
}
}
}
Try this
public class MainActivity extends AppCompatActivity {
private ProgressDialog progress;
Handler workHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress=new ProgressDialog(this);
progress.setMessage("Saving Progress");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setProgress(0);
progress.setMax(100);
progress.setCancelable(false);
progress.show();
workHandler = new Handler(new HandlerThread("workHandlerThread").getLooper());
workHandler.post(new Runnable() {
#Override
public void run() {
//Do some work
runOnUiThread(new Runnable() {
#Override
public void run() {
progress.setProgress(/*work result*/);
}
});
}
});
}
}
The idea is you do the work on the HandlerThread bound to workHandler, and post the results back the the UI using runOnUiThread()
Related
Now I have this function for reload webView:
public void reloadWebView() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
webView.reload();
}
}, 5000);}
And it is called on onCreate function
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
reloadWebView();
}
The function works but it only runs once
Easy to solve as long as the Activity is running in foreground:
Handler handler = new Handler();
public void reloadWebView() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
webView.reload();
reloadWebView();
}
}, 5000);}
Note that handler is now a field, out of reloadWebView().
Now call it in your onCreate():
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
reloadWebView();
}
Here is code to update your webview after x seconds
new CountDownTimer(5000, 1000) {
public void onTick(long millisUntilFinished) {
webView.reload();
//here you can have your logic to reload webview
}
public void onFinish() {
// hide progress bar if any
}
}.start();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG,"OnCreate()");
setContentView(R.layout.activity_main);
mToolbar = findViewById(R.id.my_toolbar);
mTextview = findViewById(R.id.title);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragment, new OneFragment());
//ft.commit();
ft.addToBackStack("frag");
ft.commitAllowingStateLoss();
}
}, 5000);
}
after minimizing my android app again its opening automatically.please help me to solve this problem
The Correct way to manage the handler is,
In your activity add this code,
private void initTasks() {
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
startActivity(new Intent(SplashActivity.this, MainActivity.class));
finish();
}
};
handler.postDelayed(runnable, 5000);
}
#Override
protected void onResume() {
super.onResume();
initTasks();
}
Then to stop opening your app after minimizing,
#Override
protected void onStop() {
super.onStop();
handler.removeCallbacks(null);
}
I have a Runnable on a UIThread updating a SeekBar while a MediaPlayer is playing. Yet, when I switch to another activity my application crashes with an exception cause the Runnable keeps on forever even after the MediaPlayer has been destroyed.
This is my code:
public class Guide extends AppCompatActivity implements MediaPlayer.OnPreparedListener {
Button back;
private MediaPlayer m_audio_player;
private Handler m_handler_seek_bar = new Handler();
private SeekBar m_seek_bar;
private Runnable m_seek_bar_runnable;
private void set_up_audio(){
m_audio_player = MediaPlayer.create(this, g_audio[NativeLib.get_active_landmark()] );
m_audio_player.setOnPreparedListener(this);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_guide);
implement_back_button();
set_up_audio();
}
#Override
protected void onStart() {
super.onStart();
set_up_seek_bar();
}
private void set_up_seek_bar() {
m_seek_bar = (SeekBar) findViewById(R.id.seek_bar);
m_seek_bar.setMax(m_audio_player.getDuration());
m_seek_bar_runnable = new Runnable() {
#Override
public void run() {
if(m_audio_player != null ){
m_seek_bar.setProgress(m_audio_player.getCurrentPosition());
}
m_handler_seek_bar.postDelayed(this, 1000);
}
};
// update Seekbar on UI thread
Guide.this.runOnUiThread(m_seek_bar_runnable);
m_seek_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) { }
#Override
public void onStartTrackingTouch(SeekBar seekBar) {}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(m_audio_player != null && fromUser){
m_audio_player.seekTo(progress);
}
}
});
}
#Override
protected void onStop() {
if (debug_mode) Log.d(TAG, "onStop");
if (m_audio_player.isPlaying()) {
m_audio_player.stop();
}
m_audio_player.release();
super.onStop();
findViewById(R.id.activity_guide).removeCallbacks(m_seek_bar_runnable);
}
// return button
private void implement_back_button() {
final Intent intent = new Intent(/* pointing at some other activity */);
back = (Button) findViewById(R.id.back_button);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(intent);
}
});
}
}
You need to use:
m_handler_seek_bar.removeCallbacks(m_seek_bar_runnable);
to remove the runnable from handler
#Override
protected void onStop() {
if (debug_mode) Log.d(TAG, "onStop");
if (m_audio_player.isPlaying()) {
m_audio_player.stop();
}
m_audio_player.release();
m_handler_seek_bar.removeCallbacks(m_seek_bar_runnable);
super.onStop();
}
Alternatively you can override the onPause() method of the activity:
#Override
protected void onPause() {
m_handler_seek_bar.removeCallbacks(m_seek_bar_runnable);
super.onPause();
}
Remove all the callbacks from the Handler in onStop using handler.removeCallbacks
In my application i want to close it after 5 seconds using Timer() function.It works when i am in MainActivity but when i go to another activity then the application do not close.Now how to run this Timer() function in background if i switch activity.What to do in this case?
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
finish();
}
}, 5000); // Application will be closed after 5 seconds
You achieve this using broadcast receiver. in your activity which you want to finish you need to create broadcast receiver.
public class TestActivity extends Activity {
public static String intent_filter_finish = "com.test.finish";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
registerReceiver(finishReceiver,
new IntentFilter(intent_filter_finish));
}
#Override
protected void onDestroy() {
unregisterReceiver(finishReceiver);
super.onDestroy();
}
BroadcastReceiver finishReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
}
now in your second activity you need to send broadcast after 5 second e.g.
public class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
sendBroadcast(new Intent(TestActivity.intent_filter_finish));
}
}, 5000);
}
}
or other possible way is directly use postDelayed() method in your test activity e.g.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
finish();
}
}, 5000);
I want to make a thread which will change the layout of my activity ... I have 2 layouts : welcomepage and activity_main ...
The goal of thread: when I launch my application , the welcomepage layout will be visible in only 5 sec and after that the layout again will be activity_main ...
I wrote the code as below:
package com.example.tripolimazad;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
public TextView counter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcomepage);
counter = (TextView) findViewById(R.id.Counter);
Thread th=new Thread(){
#Override
public void run(){
try
{
Thread.sleep(10000);
setContentView(R.layout.activity_main);
}catch (InterruptedException e) {
}
}
};
th.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
but it doesnt work !!! have anyone any solution plz !
You cannot change the UI on a non-UI thread, however in an Activity, you can use the runOnUiThread method:
runOnUiThread(new Runnable() {
#Override
public void run() {
setContentView(R.layout.activity_main);
}
});
This seems very strange though, to have this in your onCreate.
You may also try to use CountDownTimer something like:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcomepage);
//display the logo during 5 secondes,
new CountDownTimer(5000,1000){
#Override
public void onTick(long millisUntilFinished){}
#Override
public void onFinish(){
//set the new Content of your activity
MainActivity.this.setContentView(R.layout.main);
}
}.start();
//...
}
See Displaying logo for few seconds at application start for more.
Alternatively you can use a handler to avoid creating a new thread as following:
getWindow().getDecorView().getHandler().postDelayed(new Runnable() {
#Override public void run() {
setContentView(R.layout.activity_main);
}
}, 10000);
UI related operations must be done on UI thread only and must not be done in non-UI thread as you are doing. But you can update UI from non-UI thread as follows:
activityContext.runOnUiThread(new Runnable() {
#Override
public void run() {
setContentView(R.layout.activity_main);
}
});
However a better approach for the situation you mentioned is to use an Async task, provided by the Android.You can try following :
/*
* Activity/Thread to display the **welcomepage**
* when the app is started.
*/
public class SplashActivity extends Activity {
// how long until we go to the next activity
protected int _splashTime = 5000; // 5 seconds
// thread to display welcome page
private Thread splashTread;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_welcome_page_layout);
// thread for displaying the WelcomeScreen
splashTread = new Thread() {
#Override
public void run() {
try {
synchronized (this) {
// wait 5 sec
wait(_splashTime);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// finish the current splashactivity
finish();
// start MainActivity as next activity
startActivity(new Intent(SplashActivity.this, MainActivity.class));
}
}
};
// start the thread.
splashTread.start();
}
}