I have this code in android. But when the Thread begging the loading in freezing. How can I prevent this freezing happens. Here is the code related the issue:
private void reload(final String criteria) {
try {
myProgressDialog = ProgressDialog.show(myfiles.this,
"Please wait...", "Loading Your Photos... Please Wait",
false);
new Thread() {
public void run() {
try {
Thread.sleep(2000);
} catch (Exception e) {
}
runOnUiThread(new Runnable() {
#Override
public void run() {
// Fetch the fact
try {
/* here my code */
} catch (Exception e) {
myProgressDialog.dismiss();
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
// Dismiss the Dialog
myProgressDialog.dismiss();
}
}.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It would be great if someone can check
By using runOnUiThread you are doing your intensive load task on the UI thread which will freeze the UI. You want to run your task in a background thread, and then on task completion update the ui.
Thread task = new Thread(new Runnable() {
void run() {
//load some data.
// notify UI thread using Handler
}
});
task.start();
Related
I am new in Android development. I am trying to show a ProgressDialog. I see lots of tutorial that say for showing dialog must use thread. As you can see snippet code is using thread.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
refreshFromFeed();
} catch (InterruptedException e) {
e.printStackTrace();
}
setContentView(R.layout.activity_main);
}
private void refreshFromFeed() throws InterruptedException {
ProgressDialog dialog = ProgressDialog.show(this,"Loading","Wake up after some sleep");
Thread th = new Thread(){
public void run(){
Log.d("TimeFrom", String.valueOf(System.currentTimeMillis()/1000));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("TimeTo", String.valueOf(System.currentTimeMillis()/1000));
}
};
th.start();
dialog.dismiss();
}
protected void onRefresh(View view) throws InterruptedException {
refreshFromFeed();
}
The log shows it took 5 second, however, I cannot see any dialog on my screen and I can do anything on the screen. Even I use on a physical device. I've used debugging mode. There is no exception.
onRefresh is an event by onClick that declared on it's xml.
I've made a little bit changes of your code read it carefully.
private void refreshFromFeed() throws InterruptedException {
ProgressDialog dialog = ProgressDialog.show(this,"Loading","Wake up after some sleep");
Thread th = new Thread(){
public void run(){
Log.d("TimeFrom", String.valueOf(System.currentTimeMillis()/1000));
try {
Thread.sleep(5000);
dialog.dismiss();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("TimeTo",String.valueOf(System.currentTimeMillis()/1000));
}
};
th.start();
}
private void refreshFromFeed() throws InterruptedException {
final ProgressDialog dialog = ProgressDialog.show(getActivity(),"Loading","Wake up after some sleep");
Thread th = new Thread() {
public void run() {
Log.d("TimeFrom", String.valueOf(System.currentTimeMillis() / 1000));
try {
Thread.sleep(5000);
dialog.dismiss(); // dismiss your dialog here
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("TimeTo", String.valueOf(System.currentTimeMillis() / 1000));
}
};
th.start();
}
You still run the ProgressDialog in your UI thread.
ProgressDialog dialog = ProgressDialog.show(this,"Loading","Wake up after some sleep");
New thread created after this line, not before this line!
You are dismissing your dialog just right after showing it.
Maybe you want to move your "dialog.dismiss();" to inside the thread. Remember that you need to dismiss the dialog on UI Thread, otherwise it will crash your app:
private void refreshFromFeed() throws InterruptedException {
final ProgressDialog dialog = ProgressDialog.show(this,"Loading","Wake up after some sleep");
Thread th = new Thread(){
public void run(){
Log.d("TimeFrom", String.valueOf(System.currentTimeMillis()/1000));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("TimeTo", String.valueOf(System.currentTimeMillis()/1000));
runOnUiThread(new Runnable() {
#Override
public void run() {
dialog.dismiss();
}
});
}
};
th.start();
}
I see lots of tutorial that say for showing dialog must use thread.
You don't explicitly need a thread to show a ProgressDialog, this is just an example to dismiss it after 5000 ms
I have a little problem. In my android app, i have to connect to an online server.
The connection should be called with an click-button an as an backround service. I know that I must put the network connection in a thread, but i don't know how it works.
I put the call in a own method wich creates a thread but at compilation i got a error message.
here is my code:
Button:
ImageView refresher = (ImageView)findViewById(R.id.imgRefresh);
refresher.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
httpThread();
}
});
thread method:
private void httpThread(){
final Handler h = new Handler();
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
h.post(new Runnable(){
#Override
public void run() {
try{
vomServerholenUndSpeichern();
FileInputStream inStream = null;
try {
inStream = openFileInput("test.xml");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
leseDatei(inStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
createListView("test.xml");
System.out.println(inStream);
drawListView();
} catch (Exception e){
e.printStackTrace();
}
}
});
}
});
thread.start();
}
Can someone help me to fix the problem?
You have to use AsyncTask, is not difficult.
AsyncTask are necessary to avoid block UI during your connection operation, the method doInbackGround of AsyncTask is used for this kind of operations (it runs in a thread different from the UI), while int the onPostExecute (this run on the UI) of the task you will manage your httpResult;)
I have a BroadcastReceiver.
There I create a new Thread.
How can I show a toast in that thread?
Thanks
Use below code for perform UI operation from non-UI thread
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// your stuff to update the UI
}
});
Try This code
public void start_insert() {
pDialog.show();
new Thread() {
#Override
public void run() {
int what = 0;
try {
// Do Something in Background
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
what = 1;
e.printStackTrace();
}
handler22.sendMessage(handler22.obtainMessage(what));
}
}.start();
}
private Handler handler22 = new Handler() {
#Override
public void handleMessage(Message msg) {
pDialog.dismiss();
Toast.makeText(getApplicationContext(), "SuccessFull",
10).show();
}
};
Activity_Name.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// your stuff to update the UI
}
});
Use this code to update UI thread or execute any UI related operation.
I'm trying to automatically refresh JmDNS services in the background. Nothing is happening when I try:
#Override
public void onDestroy() {
try {
hiNeighborService.unregisterListener(this);
this.unbindService(this.serviceConnection);
} catch (Exception ex) {
Log.e(LOG_TAG, "Exception occur during destroying the app.");
}
super.onDestroy();
}
#Override
public void onStart() {
/*new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
refreshServices();
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();*/
ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
// This schedule a runnable task every 2 minutes
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
rebindService();
refreshServices();
}
}, 0, 1, TimeUnit.SECONDS);
super.onStart();
}
#Override
public void onRestart() {
/*new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
refreshServices();
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();*/
ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
// This schedule a runnable task every 2 minutes
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
rebindService();
refreshServices();
}
}, 0, 1, TimeUnit.SECONDS);
super.onRestart();
}
#Override
public void onResume() {
/*new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
refreshServices();
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();*/
ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
// This schedule a runnable task every 2 minutes
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
rebindService();
refreshServices();
}
}, 0, 1, TimeUnit.SECONDS);
super.onResume();
}
This is my resfreshServices() method:
private void refreshServices() {
Log.i(LOG_TAG, "Refresh available neighbors...");
final List<Neighbor> activeNeighbors = this.hiNeighborService
.getActiveNeighbors();
Log.d(LOG_TAG, activeNeighbors.size() + " active neighbors are found!");
new Thread(new Runnable() {
public void run() {
Log.i(LOG_TAG, "refresh UI...");
try {
synchronized (activeNeighborsViewModel) {
activeNeighborsViewModel.clear();
for (Neighbor neighbor : activeNeighbors) {
NeighborViewModel vm = new NeighborViewModel(
neighbor);
vm.setNeighborUnreadCount(ConnectActivity.this
.getUnreadMessageCount(neighbor));
if (activeNeighborsViewModel.contains(vm)) {
activeNeighborsViewModel.remove(vm);
}
activeNeighborsViewModel.add(vm);
}
}
notifyServiceListChanged();
Log.i(LOG_TAG, "refresh completed!");
} catch (Exception ex) {
ex.printStackTrace();
Log.e(LOG_TAG, ex.toString());
}
}
}).start();
}
Normally that gets call when a button is clicked however I would like it to be automatic. This code doesn't do anything unless I hit the Resfresh button that call resfreshServices(). I attempted to try it with threads but the activity closes and so does the app. Any ideas?
First a little comment on your code. Why are you implementing the same code three times in three different methods. I assume that you are programming android (loking at your method names). The method onresume is executed every time the activity is started or resumed. See this link for more information on this topic.
Ok, then... Did you already check the docs for more information about the ScheduledExecutorService?
Now for the jmdns issue. The jmDns library has a build in functionality to update the services. you can listen to new services and take the appropriate action when new services are available. I do not think, that repeated polling of the services is the right approach.
Look here for a little tutorial on using jmdns in android.
I am trying to figure out how to have a progress bar that says "Loading. Please Wait..." while my media player prepares a streaming file. What occurs now is that it displays after the song is prepared. how can i fix this?
mediaPlayerLoadingBar =ProgressDialog.show(PlaylistActivity.this, "", "Loading. Please wait...", true);
/*dubstep stream*/
try {
dubstepMediaPlayer.setDataSource(dubstepPlaylistString[0]);
dubstepMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
dubstepMediaPlayer.prepare();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dubstepMediaPlayer.start();
if(dubstepMediaPlayer.isPlaying()){
mediaPlayerLoadingBar.dismiss();
}`
EDIT:
This is the code I have now:
`switch(pSelection){
case 1:
new AsyncTask<Void, Void, Void>(){
#Override
protected void onPreExecute(){
mediaPlayerLoadingBar =ProgressDialog.show(PlaylistActivity.this, "", "Loading. Please wait...", true);
try {
dubstepMediaPlayer.setDataSource(dubstepPlaylistString[0]);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dubstepMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
//mediaPlayerLoadingBar =ProgressDialog.show(PlaylistActivity.this, "", "Loading. Please wait...", true);
return null;
}
protected void onPostExecute(Void result){
//mediaPlayerLoadingBar =ProgressDialog.show(PlaylistActivity.this, "", "Loading. Please wait...", true)
dubstepMediaPlayer.prepareAsync();
dubstepMediaPlayer.start();
mediaPlayerLoadingBar.dismiss();
}
}.execute();`
If someone Still facing this problem here is the code below
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
if(translation.equals("NIV"))
{
if(AudioPlaying==false)
{
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(Main.this);
mediaController = new MediaController(Main.this);
}
else
mediaController.show();
}
else
Toast.makeText(getBaseContext(), "عفوا, جاري تحميل ملفات الصوت الخاصة بترجمة الفانديك ", Toast.LENGTH_LONG).show();
pd = new ProgressDialog(Main.this);
pd.setTitle("Processing...");
pd.setMessage("Please wait.");
pd.setCancelable(false);
pd.setIndeterminate(true);
pd.show();
}
#Override
protected Void doInBackground(Void... arg0) {
try {
//Do something...
//Thread.sleep(5000);
try
{
mediaPlayer.setDataSource(AudioUrlPath);
mediaPlayer.prepare();
mediaPlayer.start();
AudioPlaying=true;
}
catch (IOException e) {
Log.e("AudioFileError", "Could not open file " + AudioUrlPath + " for playback.", e);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if (pd!=null) {
pd.dismiss();
//b.setEnabled(true);
}
}
};
task.execute((Void[])null);
The issue lies in that you are not doing anything asynchronously here, and you should be. You should use an AsyncTask to do your work.
Take a look at 'the 4 steps', as detailed here:
The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread immediately after the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
EDIT:
You can create an anonymous inner class to do your bidding, which may be similar to how you are creating your onClick handler. In your onClick do something like this:
//pseudo-code...
onClick(View v, ...) {
new AsyncTask<Generic1, Generic2, Generic3>() {
protected void onPreExecute() {
// do pre execute stuff...
}
protected Generic3 doInBackground(Generic1... params) {
// do background stuff...
}
protected void onPostExecute(Generic3 result) {
// do post execute stuff...
}
}.execute();
}
Don't forget to keep an eye on your generics here!
Here is the activity class.Here i am showing the way only.
package com.android.mediaactivity;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
public class MediaActivity extends Activity
{
public LinearLayout mainLayout;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainLayout=(LinearLayout)findViewById(R.id.mainlinear);
MediaPlayer media=new MediaPlayer(this);
media.startPlayer();
}
}
Here is mediaplayerclass.
package com.android.mediaactivity;
import java.io.IOException;
import android.media.MediaPlayer.OnPreparedListener;
public class MediaPlayer implements OnPreparedListener {
MediaActivity mediaActivity;
android.media.MediaPlayer mediaPlayer;
public MediaPlayer(MediaActivity mediaActivity) {
this.mediaActivity = mediaActivity;
}
public void startPlayer() {
mediaPlayer = new android.media.MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.reset();
try {
mediaPlayer.setDataSource("");
mediaPlayer.prepareAsync();
toggleProgress(true);
} catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void onPrepared(android.media.MediaPlayer mp) { toggleProgress(false); mediaPlayer.start(); }
public void toggleProgress(final boolean show) {
mediaActivity.runOnUiThread(new Runnable() {
public void run() {
if (show) mediaActivity.mainLayout.setVisibility(mediaActivity.mainLayout.VISIBLE);
else mediaActivity.mainLayout.setVisibility(mediaActivity.mainLayout.INVISIBLE);
}
});
}
}
}
}
And here is the main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="#+id/mainlinear"
android:visibility="invisible">
<ProgressBar android:id="#+id/ProgressBar01"
android:layout_width="wrap_content" android:layout_height="wrap_content"></ProgressBar>
</LinearLayout>
When you say prepare on the underlying mediaplayer object, internally it really does some preparation like - setting up the extractor for the file, setting up the audio decoder to decode the encoded audio file and setting up the audio sink to play the raw audio data that was decoded from the decoder. Now all this will take time, it is not instantaneous.
So in your original code, you check if the mediaplayer isPlaying and then dismiss it but the problem is at that point of time the mediaplayer is not playing the audio yet and thus your dismiss is never called so it always visible.
What you need to do is implement the listener MediaPlayer.OnPreparedListener and when the method onPrepared is called in your application call the dismiss mediaPlayerLoadingBar.dismiss(); in that method.
Here is my solution :
The prepareAsync function used to prepare the audio and it is a non blocking operation (it is not blocking the main thread of the app).
Then I used the callback setOnPreparedListener to get notified when the
prepareAsync return, and the audio is ready
public void playAudio(String audioFile){
//init the progress dialog
final ProgressDialog progressDialog = new ProgressDialog(SubjectActivity.this);
try {
progressDialog.setCancelable(false);
progressDialog.setMessage(" Waiting to Prepare ...");
progressDialog.show();
// pass the url file to the media player
mediaplayer.setDataSource(audioFile);
mediaplayer.prepareAsync();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//the callback gets called when prepareAsync audio file become ready,
mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaplayer.start();
// cancel the dialog
progressDialog.cancel();
}
});
}
Finally found out:
Guys very Imp point:
After setting url
try {
mediaPlayer.setDataSource(url);
} catch (IOException e) {
e.printStackTrace();
}
I have added prepare_sync() and added handler cause it was crashing for big files
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mediaPlayer.prepareAsync();
ProgressDialog progressDialog = ProgressDialog.show(Player.this,
"Loading Title", "Loading Message");
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
if (progressDialog != null && progressDialog.isShowing()){
progressDialog.dismiss();
}
}
});
// might take long! (for buffering, etc)
mediaPlayer.start();
}
},500);
This code will add progressbar too.
Points:
set url
prepareasync
OnPreparedlistener
Progressbar
mp.start-done
This is my way of doing btw I have heard there is alternative Exoplayer have a look at that too !