Any suggestions for this kind of error which occurs when a UI thread is loaded with lots of loops and logical operations?
get the error message through data/anr/trace.txt from File explorer. And, also put all logical operations and loops into separate threads.
That ANR error happens when you are doing intensive work on UI thread and do not allow the user interface to refresh. Your description is a perfect match for this case.
To fix it run those operations on a different thread. You can also use AsyncTask if that's convenient in your situation. See http://developer.android.com/reference/android/os/AsyncTask.html
private class LongWork extends AsyncTask<Void, Integer, Void>
{
#Override
protected Void doInBackground(Void... arg0) {
//Do a long Task here
return null;
}
#Override
protected void onPostExecute(Void result) {
//Do what you have to do on the UI Thread
}
}
Then
LongWork work=new LongWork();
work.execute();
Related
I need to perform a very simple operation that involve network. I know that this must be done with an Async Task, because run a task that involves Network operations on main thread is bad.
Since is pretty verbose using the classic way
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//to do
return "Executed";
}
#Override
protected void onPostExecute(String result) {
//to do
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
for a method static method invocation that must download only few bits
I'm wondering if there is some more concise form or alternative that I could use.
You don't need an AsyncTask. It is just a convenience to use because it already has callback methods.
You can create a new Thread and execute your network call there.
There are many ways to create a worker thread. It depends on what are you doing with network.
If you just want to do simple network operations such as download some JSON data then get it back to update UI: use AsyncTask.
If you want to do long network operations which involve moderate to large amounts of data (either uploading or downloading): use Thread.
If you want to continuously send/receive message to/from the Internet, use HandlerThread.
So in conclusion: AsyncTask is already the simplest and easiest to use. Beside, you don't need to override all methods, just override doInBackGround() and onPostExecute() if you want to receive data.
See: Asynctask vs Thread in android
You can always use AsyncTask.execute(() -> { /* network operations */ });, the downside is you don't get any of the callbacks so I tend to only use this when prototyping or with very simple tasks.
Use an anonymous class inside a method:
public void asyncOperation () {
new AsyncTask<Task, Void, Boolean>() {
#Override
protected Boolean doInBackground(String... params) {
// Your background operation, network, database, etc
return true;
}
}.execute();
}
I'm trying to do an Android game using a Thread which repeats a loop for draw, move and others.
I have a problem with the execution of a method, which searches a value with a "do while" loop. When this method is executed, the thread does not continue until this process does not end.
What would be the best option for avoid this? Make another thread within that method? If you can give an example I'd really appreciate it.
Here's some pseudocode:
void mainLoop(){
drawElements();
moveElements();
//...
//...
reposition();
}
void reposition(){
// this stops my thread
do{
// do stuff
}while(!end);
// do stuff
}
As wqrahd suggested use AsyncTask.
I assume mainLoop is a main UI thread.
public class RepositionClass extends AsyncTask {
private Context mContext;
public RepositionClass(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
// do UI related here, this function will run in main thread context.
}
#Override
protected Boolean doInBackground(String... params) {
// call non-ui(computation intensive) part of reposition function here.
return true;
}
#Override
protected void onPostExecute(Boolean result) {
// do UI related part of reposition function here.
}
}
Creating another thread won't help you if you still have to block and wait for the loop to complete the search. The problem really is what is happening in the "do stuff" loop, you just need to optimize that to solve the issue.
use asyntask and in asyntask's doInBackground , do your thread work and in asyntask's onPostExecute call your repositionMethod.
I am developing an app that needs to process acceleration values continuously for some time (approx. an hour) - yes, I would really like to do it that way. The processing involves doing some calculations and updating the UI from time to time. The acceleration is collected inside a (foreground) service - collecting acceleration should happen if the user minimizes the app as well.
My question is: what would be the most appropriate pattern to implement this? I don't want the processing to make the app UI unresponsive.
Right now I'm collecting acceleration data in the UI thread (in the Service). The collected data is than passed to a class that does some calculations and based on them broadcasts an Intent, which is registered in the Main activity to update the UI.
Should I be collecting acceleration data in a worker thread in a service? (Is this even possible)?
Or should I do the processing in another thread? (How would be the best way to do this without starving either the UI/acceleration collection thread or the processing thread)?
Thanks!
You certainly should be doing any non-trivial processing in a background thread. The easiest way sounds like it'd just be putting it into an AsyncTask called from your existing Service. You can move your processing to doInBackground. Another option would be to create a separate IntentService to handle your processing, but I think AsyncTask should be sufficient.
Try an AsyncTask
public class AsyncTaskTestActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new PostTask().execute();
}
// The definition of our task class
private class PostTask extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
displayProgressBar("Working...");
}
#Override
protected String doInBackground(String... params) {
do_background_Stuff();
// call this method whenever you want to run something in the UI thread and then get back to processing
publishProgress(i);
}
return "All Done!";
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
updateProgressBar(values[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
dismissProgressBar();
}
}
}
I have an AsyncTask in my program that seems to stop after onPreExecute(), after the app is run several times. What I mean is, I can use the app and everything works about 10-20 runs, but then it halts. Here is what's going on:
private class MyTask extends AsyncTask<String, Void, Data> {
protected void onPreExecute() {
// show loading dialog
Log.d(TAG, "end onPreExecute");
}
protected Data doInBackground(String... params) {
Log.d(TAG, "start doInBackground");
// do stuff
}
protected void onPostExecute(Data myData) {
// do stuff
}
}
When it stops working, what happens is that the loading dialog just keeps loading forever, and "end onPreExecute" prints but "start doInBackground" does not.
Why might that be?
It's hard to tell where the problem is. As your Async Task seems to work the first couple of times, it could be that this API-feature is just too "unstable" for your intention...
A solution for your issue could simply be, to replace the AsyncTask by a different Thread solution:
Here is a post where this issue was solved by a traditional Thread.
Here is a post which shows how to use an Handler.
Hope that helps!
I have several AsyncTasks doing network operations. I was recently asked to add, after each of these operations, another network call that invokes a remote service sending some statistics. I'd like this statistics call not to delay 'main' network calls, and so I was thinking of executing them in a thread created and started inside the AsyncTask's doInBackground(). This thread would most probably end after the doInBackground() and possibly the whole AsyncTask has ended. I tried this and it works, but I was wondering if there are side effects, such as memory leaks or similar?
Thanks ;)
Try starting a second AsyncTask in the first AsyncTasks 'onPostExecute' Method.
For me this worked without any issues.
If you want to start thread in doInBackground method, you can start it in onProgressUpdate() method
Example:
protected class MyTask extends AsyncTask<Void,Integer,Void> {
public static final int START_THREAD = -1;
#Override
protected void onProgressUpdate(Integer... values) {
if(values[0] == START_THREAD){
startThread();
}
}
#Override
protected Void doInBackground(Void... params) {
publishProgress(START_THREAD);
return null;
}
}