I have a service for file downloading in my service I have a Asynctask that do downloding and i am using from a content provider for save status of files .my problem is that when asynctask run any other asynctask cant run in app all of them wait till download task finish.any idea?
As of honeycomb version, AsynchTasks run in a serial executor. So if you plan to run many download jobs in parallel then what you need to do is to use an ExecutorService in your Asynchtask to do jobs in parallel.
You can also set the executor type in AsynchTask to parallel instead of sequencial when you create it, but i wont recommend that.
here are some code snippets using a Loader:
private ExecutorService executorService;
private static final int MAX_RUNNABLE_THREADS = 800;
private static final int KEEP_ALIVE_TIME = 6;
//in constructor and probably in onStartLoading...
if(this.isNetworkfast){
this.executorService = new ThreadPoolExecutor(0, MAX_RUNNABLE_THREADS
, KEEP_ALIVE_TIME
, TimeUnit.SECONDS
, new SynchronousQueue<Runnable>()
);
}else {
this.executorService = Executors.newFixedThreadPool(3);
}
//in onReset
this.executorService.shutdownNow();
try {
if (executorService.awaitTermination(20, TimeUnit.SECONDS)) {
Log.i(TAG, "executorService shutdown completed.");
}else{
Log.e(TAG, "executorService shutdown failed to finish completely.");
if(this.isErrorReportingEnabled){
this.errorMap.put("error_" + (++errorCount), "executorService shutdown failed to finish completely.");
}
}
} catch (InterruptedException e) {
Log.e(TAG, "DownloadNseQuotesAsynchTaskLoader executorService shutdown interrupted.");
if(this.isErrorReportingEnabled){
this.errorReporter.reportCustomMessagesWithException("exception_" + (++errorCount)
, "DownloadNseQuotesAsynchTaskLoader executorService shutdown interrupted.", e);
}
}
//in loadInBackground....
//do your processing to determine the number of workers/runnables needed and based on that
final CountDownLatch latch = new CountDownLatch(number of workers);
MyWorker worker = new MyWorker(latch, data set....);
this.executorService.execute(worker);
//and later in the same method we wait on the latch for all workers to finish
try {
latch.await(); //blocks the current thread until the latch count is zero
//all Workers have finished, now read in the processed data if you want
for (MyWorker worker : workers) {
SomeDataVO dataVO = worker.getData();
.......
}
} catch (InterruptedException ie) {
Log.e(TAG, "Interrupted exceltion while await on CountDownLatch running", ie);
if(this.isErrorReportingEnabled){
this.errorReporter.reportCustomMessagesWithException("exception_" + (++errorCount)
, "Interrupted exception while await on CountDownLatch running", ie);
}
}
This is not the complete piece but should be enough to give you ideas about how to use it.
All AsyncTasks background work runs serially in a background worker thread, it is designed to solve short problems.
As you probably using a long running connection, you should do this on a Thread inside a separate Service. A simple approach would be receive the connection parameter by Intent and start a new thread directly on startCommand().
Related
I have created a thread (threadName = Original) in onCreate() method of activity in android app. Now inside this thread (inside runnable), there is a for loop in which I created some new threads and then executed the threads in executorService like executorService.execute(thread), for each of them. After that, I created a timer in which I am checking that thread (Original) isAlive() and when the Thread.isAlive() is false then I call my recycler View.
Normally a thread does not die if we do not call executorService.shutdown(). But in android, it dies without the executorService being shutdown. Why this behaviour is seen in android studio?
Check with this example, our program will run indefinitely
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
}
});
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(thread1);
}
The problem is that the 'original' thread finishes once it submits new tasks to the executor, unless you block it manually. This example shows how to wait until all tasks are finished or until a specified time-out occurs:
public static void main(String[] args) {
Runnable r = () -> {
ExecutorService service = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
Runnable run = () -> {
try {
Thread.sleep(15000);
System.out.println("Stopping Thread " + Thread.currentThread().getId());
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
};
service.submit(run);
}
try {
service.shutdown(); // shuts down once all submitted tasks complete
service.awaitTermination(18, TimeUnit.SECONDS); // blocks until all tasks complete after shutdown request or until time-out occurs
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
};
Thread original = new Thread(r);
original.start();
System.out.println("is Alive? " + original.isAlive());
while (original.isAlive()) {
// blocks until thread is not alive anymore
}
System.out.println("Original Thread Stopped");
}
I'd like to point out that it is very inefficient to use a for/while loop to constantly check whether a thread is still alive or not. Instead you could implement a listener that is invoked once all threads are finished.
Here is the executor service
ExecutorService service = Executors.newCachedThreadPool();
service.shutdown() - it means cannot execute anymore runnable, it does not mean that the executor is dead.
service.awaitTermination(20, TimeUnit.SECONDS) - it means that the program will wait for 20 seconds and then it will die without finishing work. And also if the work is done before 20 seconds then everything is fine and it will die.
So in my case, after I used awaitTermination then it worked fine. My activity now waits for executor service to complete all the tasks.
So I have this method called PredictionEngine(int) that I want to run a certain number of time with a certain time-delay between each run. The method goes like this:
private void PredictionEngine(int delay) throws Exception {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
enableStrictMode();
String val = null;
try {
if (tHighPass == 0 && tLowPass == 0 && tKalman == 1) {
//Magic
} else {
//Magic
}
} catch (Exception e) {
e.printStackTrace();
}
enableStrictMode();
new DropboxTask(side_output, "Result", val).execute();
}
}, delay);
}
As obvious, I am running a network operation in the main thread as this is a research app and no client is ever going to use it.
I want this whole function to run for say a 100 times with a certain delay, say 2 seconds. The initial thought was to do this:
for(loop 100 times){
PredictionEngine(int)
Thread.sleep(2000); //sorry for StackOverflow programming.
}
However I don't want to block the main thread as I am reading some sensor data there. Any ideas for the same would be very helpful!
Thanks.
The best way to solve this is by using rxJava library, because it allow to create, modify and consume streams of events. You can implement everything in a few lines of code and modify it so operatioin will be performed in background as well.
Observable.interval(1, TimeUnit.SECONDS)
.take(100)
// switch execution into main thread
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(t -> {
doSomethingOnMainThread();
});
On the other hand, there is another solution- you can use Handler, which is usually bein used for thread communication. It has method .postDelayed() allowing you to postpone execution of task. Handler can be conveniently used along with HandlerThread. But, rxJava is more convenient and simple way to solve your problem.
While creating your Handler, you can provide a looper as one of the constructors parameters that is based on different thread then the main thread:
HandlerThread thread = new HandlerThread("Thread name", android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Looper looper = thread.getLooper();
Handler handler = new MyHandler(looper);
Messages received by MyHandler will be processed on a separated thread, leaving the UI thread clear from interferences.
To loop on the task periodically, use something like:
for (int i=0; i<100; i++){
handler.postDelayed(new Runnable(){
...
...
...
}, i*delay);
}
This way, in case you decide that the periodic tasks need to be canceled, you will always be able to invoke:
handler.removeCallbacksAndMessages(null);
I tried to solve the issue as follows without blocking the main Thread
I created the worker thread for looping and still running the predictionEngine() on main thread
MyThread t = new MyThread(2000, 3000); // delay and sleep
t.startExecution();
Worker thread class looks as follows
class MyThread extends Thread{
private int delay;
long sleep;
MyThread(int delay, long sleep){
this.delay = delay;
this.sleep = sleep;
}
#Override
public void run() {
for(int i = 0; i < 100; i++){
try {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
predictEngine(delay);
}
});
Log.i("Mtali","About to pause loop before next predict");
sleep(sleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void startExecution(){
start();
}
}
Hop this helps!
I am trying to get the server time from pubnub with the time method
mPubnub.time(callback);
I suppose it is an asynchronous call then I have a waiting loop just after so I can wait for the result
time = -1;
mPubnub.time(callback);
while(time == -1);
In the call back I have
Callback callback = new Callback() {
public void successCallback(String channel, Object response) {
try {
JSONArray jsonArray = new JSONArray(response.toString());
time = jsonArray.getLong(0) / 10000;
return;
} catch (JSONException e) {
e.printStackTrace();
}
time = 0;
}
public void errorCallback(String channel, PubnubError error) {
Log.wtf("error/" + channel, error.toString());
time = 0;
}
};
All these calls are from doInBackground of an AsyncTask. Why is it blocking my ui thread. Also calls to publish are also blocking my UI thread and I only call them from an AsyncTask
Many people say the while loop blocks the UI thread but I don't understand why that loop in an AsyncTask would block the UI thread. It wasn't in the onPostExecute or onProgressExecute. It was in doInBackground and it shouldn't block the UI.
On the other hand removing the loop still blocks the UI thread
mPubnub.time(callback);
mPubnub.publish(channel, message, true, callback);
these simple calls block the UI thread and the application stops responding.
This is blocking your UI thread:
while(time == -1);
Instead of doing that, you should handle the success/failure via the callback. If the pubnub API takes a callback like this, it would appear as though it is already handling doing it on a background thread. Just take the appropriate action inside the callback handlers.
while(time == -1);
This line blocks your UI Thread, because of this pointer will never updated by other thread, it's not a volatile variable.
You can use Debug Bottle to detect UI Block codes in your project.
When to use AsyncTask and When to use Thread as both do work in background and both can manipulate controls in UI Thread by some mechanism..
May this help you:
For long-running tasks, we use Java threads, and Android's native AsyncTask.
Basically Use AsyncTask for:
Simple network operations which do not require downloading a lot of data
Disk-bound tasks that might take more than a few milliseconds
And Use Java threads for:
Network operations which involve moderate to large amounts of data (either uploading or downloading)
High-CPU tasks which need to be run in the background
Any task where you want to control the CPU usage relative to the GUI thread
For more information refer
Mohit's answer Click Here
Edit:
Service is like an Activity but has no interface. Probably if you want to fetch the weather for example you won't create a blank activity for it, for this you will use a Service. Service is access to a Context object which has an independent life cycle. This allows for reuse of common code by many activities and, in the case of public or exposed services in many applications.
A Service runs on the main thread of the calling Component’s process by default (and hence can degrade responsiveness and cause ANRs), hence you should create a new Thread to perform long running operations.
A Thread is a Thread, probably you already know it from other part. You need to know that you cannot update UI from a Thread. You need to use a Handler for this and stopping a thread sometime become problematic also. A thread is a mechanism for doing work without blocking other work...
A service does not imply a thread and a thread does not imply a service. Both are different from eachother..
An AsyncTask is an intelligent Thread that is advised to be used. Intelligent as it can help with it's methods, and there are two methods that run on UI thread, which is good to update UI components.
AsyncTask is just a "helper" class provided with Android SDK to make it easier to skip to the UI thread after the background task is finished. It is built over the standard Java threading API. It does not give antyhing that cannot be done with Threads only. It addresses the common scenario of switching between the short task run background thread and UI thread.
Generally it is convenient to use AsyncTask when you must "skip back" to UI thread when the background task is done or when you have to give some feedback to UI thread during task execution. Otherwise it's just overhead.
You are not forced to use AsyncTask. If you as a developer prefer using Threads directly or Futures you may use it and skip to UI thread on your own manually after the background task is done.
EDIT:
Some other answers here suggest that using AsyncTask should be limited to short tasks. Allegedly because it uses a common pool. However it is no longer true since API Level 11 (so, for quite a long time). You can use executeOnExecutor instead of execute to execute AsyncTask's in dedicated thread pool. See http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor%28java.util.concurrent.Executor,%20Params...%29
Because examples are usually more communicative look at the example below.
Let's assume that we have a static function to do some heavy task and a TextView which we want to display progress and final status of the task declared as below:
static Object doHeavyTask(String string) throws Exception;
TextView progressInfo;
Execution of the task in background thread using async task would look like:
new AsyncTask<String, Integer, Exception>() {
#Override
protected Exception doInBackground(String... params) {
for (int i = 0; i < params.length; i++) {
try {
doHeavyTask(params[i]);
} catch (Exception e) {
return e;
}
publishProgress(i, params.length);
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressInfo.setText("Executed " + values[0] +
" of " + values[1] + " tasks.");
}
#Override
protected void onPostExecute(Exception result) {
if (result == null) {
progressInfo.setText("Heavy background job done successfully!");
}
else {
progressInfo.setText("Heavy background job failed!" +
"Exception message: " + result.getMessage());
}
}
}.execute("input1", "input2", "input3");
Exactly the same can be achieved with Thread:
final Handler handler = new Handler(Looper.getMainLooper());
final String[] params = { "input1", "input2", "input3" };
new Thread() {
#Override
public void run() {
for (int i = 0; i < params.length; i++) {
try {
doHeavyTask(params[i]);
} catch (final Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
progressInfo.setText("Heavy background job failed!" +
"Exception message: " + e.getMessage());
}
});
return;
}
final int currentIndex = i;
handler.post(new Runnable() {
#Override
public void run() {
progressInfo.setText("Executed " + currentIndex +
" of " + params.length + " tasks.");
}
});
}
handler.post(new Runnable() {
#Override
public void run() {
progressInfo.setText(
"Heavy background job done successfully!");
}
});
}
}.start();
As you see above using the AsyncTask is simply a bit more convenient. But there is no other advantage, just this convenience :).
If you prepared your own task encapsulating Thread (and a Handler to skip back to the UI thread) then maybe your class will be more efficient/comfortable for you to use.
That's all :).
You can run multiple threads concurrently. But asynctask is queued, meaning it is running one task at a time.
I am referring to http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/AlarmService_Service.html
There the runnable of the thread looks like this
Runnable mTask = new Runnable()
{
public void run()
{
Log.v("service", "thread is running after 5 min");
// Normally we would do some work here... for our sample, we will
// just sleep for 30 seconds.
long endTime = System.currentTimeMillis() + 15*1000;
while (System.currentTimeMillis() < endTime)
{
synchronized (mBinder)
{
try
{
mBinder.wait(endTime - System.currentTimeMillis());
}
catch (Exception e)
{
}
}
} // Done with our work... stop the service!
AlarmService_Service.this.stopSelf();
}
}
I admit that I have some problems with the concept of synchronized... The thread runs the while loop to wait 15s, within that loop I have wait for 15s. So how would the runnable look like if I just want to write a log entry e.g. Log.v(TAG,TEXT);? What would change if I want to write a new entry into my own database table?
Thanks, A.
If you just want a log statement then the following will work fine
Runnable mTask = new Runnable()
{
public void run()
{
Log.v("TAG", "Some verbose log message");
}
}
Whether you need to use synchronized on an object depends on whether object is thread-safe or not. If it is not thread-safe, then you will need to ensure that only one thread access the object at a time by using a synchronized block. In your example mBinder is not thread-safe, so in order to call the wait method of the binder you need to ensure that you are the only thread accessing it.
A runnable is most often used to execute code in a different thread, so that long running operations (such as IO, but in this case just waiting) do not block the UI thread.
Simply replace
try
{
mBinder.wait(endTime - System.currentTimeMillis());
}
catch (Exception e)
{
}
...with the code you want to execute?
Synchronized is just to assert that only one process accesses the thread at one time.