Performance enhancement failed - android

I have an ANR (Application is not responding) problem. I am trying to separate tasks into threads using AsyncTask, however it seems worse than before.
I am doing something wrong but I could not get where is the problem.
As you can see, the main thread takes 6M milliseconds which is not good I think.
To increase performance, I did those things in onCreate() methods of different activities:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
//TODO your background code
if(sPreferenceManager.getBoolean(Constants.SharedPreferences.UPDATE_REQUIRED))
{
log(Log.DEBUG,"mediaplayeractivity","UPDATE_REQUIRED");
mViewModel.getmInteractor().updateDatabaseAfterLogin();
}
}
});
AsyncTask.execute(new Runnable() {
#Override
public void run() {
//TODO your background code
initServices(savedInstanceState);
}
});
AsyncTask.execute(new Runnable() {
#Override
public void run() {
Fabric.with(GomusApplication.this, new Crashlytics());
//TODO your background code
AndroidThreeTen.init(GomusApplication.this);
initPreferences();
sInstance = GomusApplication.this;
initRealm();
appComponent = DaggerAppComponent.builder()
.appModule(new
AppModule(GomusApplication.this)).build();
appComponent.inject(GomusApplication.this);
}
});
I separated tasks into AsyncTasks. However it made performance worse!
UPDATE:
I have changed my AsyncTasks like this but still I do not see any enhancement weirdly:
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
if(sPreferenceManager.getBoolean(Constants.SharedPreferences.UPDATE_REQUIRED))
{
log(Log.DEBUG,"mediaplayeractivity","UPDATE_REQUIRED");
mViewModel.getmInteractor().updateDatabaseAfterLogin();
}
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
I also made some layout changes on constraint layouts like some fields were missing and I added them. I deleted some big images to increase the performance.
However, what I did made the performance worse. It was taking 3M milliseconds to run main thread but now it is 6M milliseconds.
I am so sorry, I have never tried to increase performance until now so I do not have enough knowledge. But I have made some research and people say that use AsyncTask.
Any help would be appreciated.
Thanks!

Related

java - Can I call a Async task inside a runnable postdelayed?

I have done a counter, who handler a limit time for my loading.
Its something like: If the process spend 10s, and my loading minimum time is 15s, this counter will execute a postdelayed with 5s.
But something is wrong, cause my app is crashing.
Here is what Ive done so far, in resume:
new MyHandler(secondsLeft, new LoadingFinishedCallBack() {
#Override
public void timeFinished() {
//CALLING A ASYNC TASK HERE
}).execute();
class MyHandler {
public void execute(){
runnable = new Runnable() {
#Override
public void run() {
handler.removeCallbacks(runnable);
callback.onTimeLeftFinished();
}
};
handler.postDelayed(runnable,timeLeft);
}
}
But for some reason, my app is crashing when doInBackground is calling, inside the async task.
I dont know why, cuz the error log doesnt show anything.
Can you guys help me pls

android - Starting an event with the completion of two threads running parallel

I have two or more network calls in separated threads on main activity start, I want to show all data after network threads done.
Thread firstNetworkCallThread=new Thread(new Runnable() {
#Override
public void run() {
// network calls and get data...
}
});
Thread secondNetworkCallThread =new Thread(new Runnable() {
#Override
public void run() {
// network calls and get data...
}
});
firstNetworkCallThread.start();
secondNetworkCallThread.start();
I want these threads work parallel, and when both of them are complete, call new event to show data.
How can I do this?
Guava has a good solution for this. If you convert your Threads to ListenableFutures (also a Guava object) you can create a list of ListenableFutures and add a callback to that list.
Futures.addCallback(
Futures.allAsList(/*future1*/, /*future2*/, /*future3*/),
new AbstractDisposableFutureCallback<List<Object>>() {
#Override
protected void onSuccessfulResult(List<Object> results) {
// whatever should happen on success
}
#Override
protected void onNonCancellationFailure(Throwable throwable) {
// whatever should happen on failure
}
});
Guava also has a bunch methods such as #successfulAsList which only contains successful results or #inCompletionOrder which orders them based on when they completed and a bunch of others.
I generally tend to use Guava as it provides a fairly clean solutions to problems like these.
An example of how to creates a ListenableFuture is as follows:
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Object> explosion =
service.submit(
new Callable<Object>() {
public Object call() {
// get network data
return null; // return the data
}
});

runOnUiThread() no executing when using Thread.sleep()

I'm using code that looks like this :
_thread = new Thread(){
#Override
public void run() {
try {
while (true) {
operate();
Thread.sleep(DELAY);
}
} catch (InterruptedException e) {
// Doesn't matters...
}
}
};
operate function looks like this :
// does things....
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// adds an ImageView to the screen
}
});
// does other things...
At the bottom line, what i wanted to achieve is an operation that happens once in a while, without interrupting the main thread and the UI, something like a game-loop.
In the first 2 times that operate() runs, it adds the ImageView and everything is alright, but after 2 or 3 times it stops adding the ImageViews, but the UI is still running as usual. When i debugged the problem, i found out that after 3 times the run() method of the Runnable isn't called anymore, even thought the operate function was called.
The wired thing (for me) was that when i removed the Thread.sleep, everything worked fine (much faster of course...). I tried to replace it with a very long for loop (just for checking) and it worked, but of course it is not an appropriate solution to the problem.
I read about the problem, most of the people that asked this question did a thread.sleep or an infinite loop on the main thread, but, as i see it, i didn't do such thing. Many people wrote that you should replace the Thread.sleep with Handler.postDelayed. I tried to do it but it didn't work, maybe I did it wrong. I even tried replacing the runOnUiThread with other options I found on the internet, but all of them gave me the same exact results. I tried to replace the method that I'm adding the view to the activity, but all of them, again, gave the same result.
The waiting is crucial for this application. I got to find a way to wait sometime and then execute a function on the UI thread, cause this pattern returns at least a couple of times in my application.
It sounds like you want a post delay so that you can do the code on the UI thread after some delay. Handler Post Delay.
private static final int DELAY = 500;
private Handler mHandler;
private Runnable mRunnable;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start();
}
private void start()
{
mHandler = new Handler();
mRunnable = new MyRunnable(this);
mHandler.postDelayed(mRunnable, DELAY);
}
private void stop()
{
mHandler.removeCallbacks(mRunnable);
}
private void doSomething()
{
// Do your stuff here.
// Reschedule.
mHandler.postDelayed(mRunnable, DELAY);
}
Recommended way of creating a Runnable.
private static class MyRunnable implements Runnable
{
private WeakReference<MainActivity> mRef;
// In here you can pass any object that you need.
MyRunnable(MainActivity activity)
{
mRef = new WeakReference<MainActivity>(activity);
}
#Override
public void run()
{
// Safety check to avoid leaking.
MainActivity activity = mRef.get();
if(activity == null)
{
return;
}
// Do something here.
activity.doSomething();
}
}
There could be several reasons why the UI Runnable isn't being executed. Probably the activity variable has something messed up with it or it's referencing the context incorrectly, or as you said the Thread.sleep() could be causing an issue. At this point more parts of the code needs to viewed to better solve the problem.
A better way of implementing your logic is to use a scheduled Timer instead of using an infinite loop with a Thread.sleep() in it. It will execute the code within a background thread. And then use a Handler to update the UI instead of activity.runOnUiThread(). Here's an example:
// Global variable within the activity
private Handler handler;
// Activity's onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
handler = new Handler(getMainLooper());
Timer timer = new Timer("ScheduledTask");
// Timer must be started on the Main UI thread as such.
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
operate();
}
}, 0L, DELAY);
}
private void operate() {
// does things in background....
handler.post(new Runnable() {
#Override
public void run() {
// adds an ImageView to the screen from within the Main UI thread
}
});
// does other things in the background...
}

Android:getting following error "Only the original thread that created a view hierarchy can touch its views."

Here is my code for Progress Dialog in Android and i am getting following error:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. I saw all previous post related to this error but i could not correct this error.
// Waiting screen
pleaseWaitdialog = ProgressDialog.show(PhoneBookListView.this, "Loading", "Please wait...", true);
new Thread(new Runnable() {
#Override
public void run()
{
Looper.prepare();
// do the thing that takes a long time
LoadContactFromPhoneAndSim();
PhoneBookListView.this.runOnUiThread(new Runnable() {
#Override
public void run()
{
pleaseWaitdialog.dismiss();
}
});
}
}).start();
Any help will be appreciate
Thanks.
I suggest you use an AsyncTask, as they make this sort of thing easier. In general, you want to do complex stuff on a background thread, and only update the UI from the UI thread.
public class PhonebookLoader extends AsyncTask<Void,Void,Void> {
protected Void doInBackground(Void ... params) {
LoadContactFromPhoneAndSim();
return void;
}
protected void onPostExecute(Void param) {
pleaseWaitdialog.dismiss();
}
}
To start it with this class, you just call this:
new PhonebookLoader.execute();
And you can do all kinds of things with this, like publish your progress so the user knows how far they have progressed, update the UI thread after you are done loading, etc. AsyncTask is your friend, use it.
Looking at this, I suspect that PhonebookLoader is probably both loading the data and putting it on the UI. Separating these two tasks will make your app much more responsive and easier to maintain.

Why should we use aysntask or service instead of a new thread

In android why should we use a asyntask and service, instead of using a new thread() and write the necessary background functionality?
I know that we should not run long running operations like downloading a file from server on the mainthread aka UI thread. And should use a asynctask or service.
But why cant we create a new thread() {which is eventually a new thread other than the main thread} and write necessarily long running operation in that thread.
why did google create the AsyncTask and Service without suggesting to use the regular New Thread()???
thanks in advance
edit1:
may be i wasn't clear in my question or not sure, if i am, even now. help me out.
i get it, the whole point starts from
Do not block the UI thread
Do not access the Android UI toolkit from outside the UI thread
why ?
1.how much can the UI thread handle ? how can we determine a breakpoint? how is a ANR point determined? can we track?
2. when a service component handles long running operations why can't a activity component handle?
Remember that if you do use a service, it still runs in your application's main thread by default, so you should still create a new thread within the service if it performs intensive or blocking operations
http://developer.android.com/guide/components/services.html
the above statement is from android documentation.
3.why cant a service start in a new thread straight away, if we are so concerned about main thread? don't get me wrong in question 3, i am trying to understand the advantage of starting the service in main thread. by default.
in the above statement , does it suggest the main thread's ability to start and handle a service's long running operation load? if so does it contradict with question 1.
Well let's look how you'd perform a simple task using a Thread.
The first step is to create a Thread using a Runnable. Something like this:
private void fetchResultsAsync() {
Runnable runner = new Runnable() {
#Override
public void run() {
List<String> results = fetchResultsFromWebServer();
}
};
new Thread(runner).run();
}
The thing is, we need to show the results so it would actually be more like this:
private void fetchResultsAsync() {
Runnable runner = new Runnable() {
#Override
public void run() {
List<String> results = fetchResultsFromWebServer();
workFinished(results);
}
};
new Thread(runner).run();
}
private void workFinished(List<String> results) {
// show the results on the UI
}
It looks good, but there's a problem; the callback method (workFinished) has to update the UI. If we do this from any non-main thread, there will be big problems. We need a thread-safe way to call that method, which is what Handlers are for. Let's also throw in a method for updating our progress, which is very common. The code would now look like this:
private final Handler myHandler = new Handler();
private void fetchResultsAsync() {
Runnable runner = new Runnable() {
#Override
public void run() {
List<String> results = fetchResultsFromWebServer();
workFinished(results);
}
};
new Thread(runner).run();
}
private void showProgress(int result) {
myHandler.post(new Runnable() {
#Override
public void run() {
// update a progress bar here
}
});
}
private void workFinished(final List<String> results) {
myHandler.post(new Runnable() {
#Override
public void run() {
// show the results on the UI
}
});
}
Compare this to the implementation using an AsyncTask:
private void fetchWithTask() {
new AsyncTask<Void, Integer, List<String>>() {
#Override
protected List<String> doInBackground(Void... params) {
return fetchResultsFromWebServer();
}
#Override
protected void onPostExecute(List<String> strings) {
// show the results on the UI
}
#Override
protected void onProgressUpdate(Integer... values) {
// update a progress bar here
}
}.execute();
}
It doesn't differ much by lines of code, but it's much more obvious what needs to happen and where. It protects you from nasty mistakes like forgetting to wrap UI-touching code in a Runnable that has to be posted to a UI-Thread-owned Handler.
Now imagine that you have several different types of small background tasks that need to be performed. It would be very easy to call the wrong showProgress or workFinished method from the wrong background Thread because you have to plug all those pieces together yourself.
There's also a very nasty bug lurking in the use of Handler's default constructor. If the containing class is first referenced by a non-UI thread during runtime, the Handler would belong to that Thread. AsyncTask hides always does things on the correct Thread. This is hard to catch!
At first blush AsyncTasks don't seem all that useful, but the callback plumbing is where they really pay off in spades.
"instead of using a new thread() and write the necessary background functionality?"
Why rewrite the background functionality? AsyncTask does it for you. As njk2 mentioned a Service is not really a fair comparison, though IntentService automatically creates a new thread for you in onHandleIntent().
edit: To answer your other questions, blocking the UI thread, will block all user interaction and the app will appear to "freeze". Definitely not something we want to do at all.

Categories

Resources