can i handle android ANR? and change msgdialog? - android

there are ANR when I play some net clip, and I can't handle the error msg from MediaPlayer.
Can I handle ANR msg from system and change the dialog? the default dialog is not comfort to user.

You cannot handle ANR in your own application. You should try your best to avoid the ANR.
According to Android dev guide pages, the ANR is triggered by the following conditions:
No response to an input event (such as key press or screen touch events) within 5 seconds.
A BroadcastReceiver hasn't finished executing within 10 seconds.
So, you should look cat the logcat traces and the ANR traces to target the position where ANR occurs and check the source code to find any possible 'long-running operations' that might be blocking the main thread.
Try to use AsyncTask to carry the task in the background to avoid ANR, which is recommend by Android official site. Take the downloading for example:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// Do the long-running work in here
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
// This is called each time you call publishProgress()
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
// This is called when doInBackground() is finished
protected void onPostExecute(Long result) {
showNotification("Downloaded " + result + " bytes");
}
}
To execute this worker thread, simply create an instance and call execute():
new DownloadFilesTask().execute(url1, url2, url3);

Related

Stopping a thread in Android is deprecated

I am working on an Android project and I have a thread which is posting to a PHP API and does checks with the response.
Before the thread starts I show a progress dialog which can be cancelled. When the cancel is pressed I call thread.stop() but this shows up as deprecated.
Everything I have found on Google suggest that I have a flag and check the flag within the while loop and come out of the thread cleanly, however in my circumstances there is no loop, so how should I go about doing this?
The problem you are facing is know problem because, threads are not supposed to be stopped by calling thread.stop(); method.
Also Android discourages the use of Java Threads in Android, and Conveniently, Android has some additional support for when it comes to communicating between Threads, The Handler class provides a neat queued message mechanism, and Looper provides a handy method for processing same.
But as you mentioned you want to show a progress dialog which can be cancelled. When the cancel is pressed, so this type of functionality can be achieved using AsyncTask.
As AsyncTask is one of the easiest ways to implement parallelism in Android without having to deal with more complex methods like Threads.
Though it offers a basic level of parallelism with the UI thread, it should not be used for longer operations (of, say, not more than 2 seconds).
Mainly AsyncTask should handle your problem, Since:
It provides easy and standard recommended mechanism to publish background progress (see the Usage section here:
http://developer.android.com/reference/android/os/AsyncTask.html)
It provides method cancel(boolean); for cancelling a task(see the Cancelling a task section here:
http://developer.android.com/reference/android/os/AsyncTask.html
AsyncTask has four methods to do the task:
onPreExecute();
doInBackground();
onProgressUpdate();
onPostExecute();
And cancel(); method to handle the cancellation of the background work.
Where doInBackground() is the most important as it is where background computations are performed.
Code:
Here is a skeletal code outline with explanations:
public class AsyncTaskTestActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// This starts the AsyncTask
// Doesn't need to be in onCreate()
new DownloadFilesTask().execute(url1);
}
// Here is the AsyncTask class:
//
// AsyncTask<Params, Progress, Result>.
// Params – the type (Object/primitive) you pass to the AsyncTask from .execute()
// Progress – the type that gets passed to onProgressUpdate()
// Result – the type returns from doInBackground()
// Any of them can be String, Integer, Void, etc.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
}
For more in depth knowledge visit following links:
https://blog.nikitaog.me/2014/10/11/android-looper-handler-handlerthread-i/
http://developer.android.com/reference/android/os/AsyncTask.html

AsyncTask and getting/updating Data

I can easily get data from the database.. But because Asynctask runs in the background, it has not downloaded the data before i call my update() method.
Example.
MyGetDataFromDatebaseCall();
UpdateSomething();
So here's my question. How can you make the UpdateSomething() method wait until the MyGetDatebaseCall() has downloaded alle the data?
I have made a Dialog window that pops up, so the user have to press okay to proceed and that works. I could also create 2 buttons so they call one method each. But they are such ugly solutions. I have also tried to send an instance of the Activity i was in, and making the AsyncTask class try and update the Activity class in the doInBackground, but apperently it cant be done?
You should call MyGetDataFromDatebaseCall() method in doInBackground() and after downloading all the data, you can call updateSomething() method in onPostExecute().
It will work fine.
Did you ever look at the documentation?
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}

How to know that a thread is finished [duplicate]

This question already has answers here:
How to know if other threads have finished?
(12 answers)
Closed 7 years ago.
I have an activity in which i am running a thread to hit the web service.i want to finish the activity only when the thread is finished.
To make your life easier use Android AsyncTask Object. This provides the same background process as a Thread but handles everything for you. This includes callbacks at different stages of the AsyncTask. This includes once it has finished doing what you ask of it in the background via the onPostExecute() function.
From the documentation:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
You can use Thread.join(), which works for all Java programs (not just Android).
You can call isAlive() method of your Thread or getStatus() if you use AsyncTask

How to notify activity about sync errors when using SyncAdapter

I have a table called student which I want to populate from the server. In my activity I show a progress bar and call ContentProvder.requestSync(Content URI of student..). Now if I understand correctly as per Virgil's talk I should add an observer on the ContentURI of the student to be notified later by the ContentProvider when the sync finishes. But what happens if say there was a network error. The student table will never be populated and my progress dialog will never be removed.
I understand the
"broadcast receiver approach"
mentioned in another thread but that deviates from Virgil's approach which I consider ideal.
Also on those lines why doesn't the requestSync allow to pass a ResultReceiver as part of the extras. Isn't that generally a Service talks back to an Activity?
A SyncAdapter is not meant to be used for this kind of scenario. SyncAdapter is meant for background sync of data, invisible to the user.
Your case sounds like perfect for a AsyncTask. With that you can use publishProgress() to update your progress bar while your network task happens in another thread. You can find a lot of information and examples on AsyncTask online.
Example from the link above:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
run it by executing it like so:
new DownloadFilesTask().execute(url1, url2, url3);
Here is another example, with tutorial (simply found by google):
http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/

Android with thread shows error

In the application i called the Thread in the alerdialog click listener.
It shows the Error "Force to close the application" in the Mobile Samsung pro.
but when i execute the same code in the another application then code works correctly...
It's probably because you're doing something wrong in the alerdialog click listener. Do the thing you're doing wrong right and it won't show the Error.
Do this below procedure help full in ur app
Android also provides something called AsyncTask which is specifically designed for running some stuff on a separate thread, and some on the UI thread. This automatically uses Android's threadpool, and if you do not have any reason to use an explicit separate thread, is an easy, clean way to go:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// Runs on a ThreadPool thread
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
// Sends data to onProgressUpdate to run on the UI thread
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
// Runs on the UI thread!
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
// Runs on the UI thread!
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}

Categories

Resources