How to perform background process in android? - android

I am performing some operations(uploading image to webservice) in IntentService.
Please see my code below.
Inside the activity i am calling service like this.
I am calling the below method after capturing the image i.e. inside onActivityResult. The app is getting hanged when i call this method in onActivityResult. I am able to perform the task in IntentService. But the acitivity is getting hanged.
private void callService(){
Intent intent = new Intent(this, TestIntentService.class);
intent.putExtra("imageData", imageData);
startService(intent);
}
This is my IntentService Class.
Can i perform webservice call inside callImageUploadAPI().
Am i doing anything wrong here?
public class TestIntentService extends IntentService {
public TestIntentService() {
super("com.screens.testapp");
// TODO Auto-generated constructor stub
}
//imageData passed from the activity
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
if(intent != null){
Bundle extras = intent.getExtras();
imageData= extras.getString("imageData");
}
callImageUploadAPI(imageData);
}
private void callImageUploadAPI(final String imageData) {
// TODO Auto-generated method stub
try {
if (Log.checkNetworkStatus(TestIntentService.this)) {
} else {
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
Thanks

If you need to do a task in background, Android provides a class called AsyncTask which you can extend and use it for doing a network operation or any other heavy operation. This is an example from Android Developer Website (AsyncTask Page):
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");
}
}
This may be used in your code this way:
if (Log.checkNetworkStatus(TestIntentService.this)) {
new DownloadFilesTask().execute(url1, url2, url3);
} else {
}

For you to perform actions in the background use Services.
You can launch the services from your activity and you can assign a thread for the service and a handler for communication from that thread to the UIThread.
Check this: http://developer.android.com/guide/components/services.html
A little sneak peek
A Service is an application component that can perform long-running operations in the background and does not provide a user interface.

Related

how to automatically invoke a method in android?

im building an android application that recive images from arduino uno in order to show them continously as a video , i write an asyncTask that reads image and show it in image view , how can i invoke this method every seconed automatically .
here is my asyncTask
I made a button that invoke the async task , but how to make it invoked continously
class myAsyncTask extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
mmInStream = tmpIn;
int byteNo;
try {
byteNo = mmInStream.read(buffer);
if (byteNo != -1) {
//ensure DATAMAXSIZE Byte is read.
int byteNo2 = byteNo;
int bufferSize = 7340;
int i = 0;
while(byteNo2 != bufferSize){
i++;
bufferSize = bufferSize - byteNo2;
byteNo2 = mmInStream.read(buffer,byteNo,bufferSize);
if(byteNo2 == -1){
break;
}
byteNo = byteNo+byteNo2;
}
}
}
catch (Exception e) {
// TODO: handle exception
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
bm1 = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
image.setImageBitmap(bm1);
}
}
If it's from a background thread, one possibility is to use an unbounded for loop. For example, suppose the AsyncTask currently does:
private class MyTask extends AsyncTask<T1, Void, T3>
{
protected T3 doInBackground(T1... value)
{
return longThing(value);
}
protected void onPostExecute(T3 result)
{
updateUI(result);
}
}
then rewrite it as something like:
private class MyTask extends AsyncTask<T1, T3, T3>
{
protected T3 doInBackground(T1... value)
{
for (;;)
{
T3 result = longThing(value);
publishProgress(result);
Thread.sleep(1000);
}
return null;
}
protected void onProgressUpdate(T3... progress)
{
updateUI(progress[0]);
}
}
Of course, you should have a check to break the loop (for example when the Activity is paused or destroyed).
Another option is to create a Handler instance and call postDelayed() repeatedly.
Handler h = new Handler();
h.postDelayed(r, DELAY_IN_MS);
Runnable r = new new Runnable() {
public void run() {
// Do your stuff here
h.postDelayed(this, DELAY_IN_MS);
}
}

Main UI freezes even when tasks are handled by AsyncTask

I made Service that runs on the background collecting data from internet using AsyncTask and storing them in Shared Preferences. Even though the work is done in AsyncTask it still freezes my main activity.
Here is the code for Service:
public class GetterService extends Service {
SharedPreferences.Editor editor;
HashMap<Integer,String> links = new HashMap<Integer,String>();
#Override
public void onCreate() {
editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
populateLinks();
}
private void populateLinks(){
// Here I add links to HashMap
}
#Override
public IBinder onBind(Intent intent) {
Toast.makeText(this, "GetterService ON BIND", Toast.LENGTH_LONG).show();
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "GetterService ON DESTROY", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
doTasks();
return super.onStartCommand(intent, flags, startId);
}
#Override
public boolean onUnbind(Intent intent) {
Toast.makeText(this, "GetterService ON UNBIND", Toast.LENGTH_LONG).show();
return super.onUnbind(intent);
}
private void doTasks(){
for (Integer in : links.keySet()) {
Document doc = null;
try {
doc = new NetTask().execute(links.get(in)).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (doc != null) {
Elements names = doc.select("strong, li");
if(names != null && names.size() > 0) {
for (int j = 0; j < names.size(); j++) {
editor.putString("header"+j, names.get(j).text().toString());
}
}
editor.commit();
}
}
}
public class NetTask extends AsyncTask<String, Integer, Document>
{
#Override
protected Document doInBackground(String... params)
{
Document doc = null;
try {
doc = Jsoup.connect(params[0]).timeout(5000).get();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return doc;
}
}
}
and here is how I start the service from main activity:
Intent startServiceIntent = new Intent(this, GetterService.class);
this.startService(startServiceIntent);
Even though the work is done in AsyncTask it still freezes my main activity.
You are using get():
doc = new NetTask().execute(links.get(in)).get();
And get() blocks the UI thread until the AsyncTask has completed, to me this method defeats the purpose of using a AsyncTask...
You should move this logic:
if (doc != null) {
Elements names = doc.select("strong, li");
if(names != null && names.size() > 0) {
for (int j = 0; j < names.size(); j++) {
editor.putString("header"+j, names.get(j).text().toString());
}
}
editor.commit();
}
Inside your NetTask's onPostExecute() method and remove get(). Now your AsyncTask won't bind-up the main thread.
It's because of the
new NetTask().execute(links.get(in)).get();
call.
AsyncTask.get() blocks until the async call has been completed. To be asynchronous you need to implement
onPostExecute()
and process the results there.
Don't call get(), just call execute(). Implement and overridden onPostExecute() to take a Document object as a parameter. onPostExecute() is called automatically when doInBackground() returns. Code in onPostExecute() is executed on the UI thread, so you can interact with the UI that way.
I suggest you take a look at the AsyncTask section in this document, http://developer.android.com/guide/components/processes-and-threads.html and the AsyncTask API page here, http://developer.android.com/reference/android/os/AsyncTask.html.
I had the similar problem and figured out what's going on. This code will not freeze UI, but if you put 'for loop' and sleep inside onProgressUpdate, then UI will be frozen during the process.
public class Karaoke extends AsyncTask<Void, Integer, Void> {
private Handler mHandler = new Handler(Looper.getMainLooper());
protected Void doInBackground(Void... urls) {
animating = true;
{
for (int i = 0;i < 6; i++)
{
publishProgress(i);
try
{
Thread.sleep(1000);
publishProgress(i);
}
catch (Exception xx){
}
}
}
animating = false;
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
if (light)
{
light = false;
iv_array[findview(egtxts[values[0]].getText() + "")].setImageResource(onpress);
}
else
{
light = true;
iv_array[findview(egtxts[values[0]].getText() + "")].setImageResource(onup);
}
}
protected void onPostExecute(Long result) {
//showDialog("Downloaded " + result + " bytes");
}
}

Determine that thread is running or not if using runnable in android

I have created a program in android for multithreading.
When I hit one of the button its thread starts and print value to EditText now I want to determine that thread is running or not so that I can stop the thread on click if it is running and start a new thread if it is not running here is mu code:
public void startProgress(View view) {
final String v;
if(view == b1)
{
v = "b1";
}
else
{
v = "b2";
}
// Do something long
Runnable runnable = new Runnable() {
#Override
public void run() {
//for (int i = 0; i <= 10; i++) {
while(true){
if(v.equals("b1"))
{
i++;
}
else if(v.equals("b2"))
{
j++;
}
try {
if(v.equals("b1"))
{
Thread.sleep(3000);
}
else if(v.equals("b2"))
{
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
// progress.setProgress(value);
if(v.equals("b1"))
{
String strValue = ""+i;
t1.setText(strValue);
}
else
{
String strValue = ""+j;
t2.setText(strValue);
}
//t1.setText(value);
}
});
}
}
};
new Thread(runnable).start();
}
#Override
public void onClick(View v) {
if(v == b1)
{
startProgress(b1);
}
else if(v == b2)
{
startProgress(b2);
}
}
Instead of that messy code, an AsyncTask would do the job you need with added readability ...
It even has a getStatus() function to tell you if it is still running.
You'll find tons of examples by looking around a bit (not gonna write one more here). I'll simply copy the one from the documentation linked above:
Usage
AsyncTask must be subclassed to be used. The subclass will override at least one method (doInBackground(Params...)), and most often will override a second one (onPostExecute(Result).)
Here is an example of subclassing:
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");
}
}
Once created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
Use a static AtomicBoolean in your thread and flip its value accordingly. If the value of the boolean is true, your thread is already running. Exit the thread if it is true. Before exiting the thread set the value back to false.
There are some way can check the Thread properties
You able to check Thread is Alive() by
Thread.isAlive() method it return boolean.
You able to found runing thread run by
Thread.currentThread().getName()
Thanks

simple process bar with asytask

I want to add a simple process bar to my code with asy task. I tryed some exampels but cant see that process bar working.
I post here my code hope you can help me.
I want to stop process bar when some of my code is done like with some flag to stop the proses bar.
plese post some code.
thanks a lot!
here my code:
private class loading extends AsyncTask<Void, Void, Integer> {
Context context;
ProgressBar progressBar;
static final long waitTime = 1 * 4000L;
long preTime;
int progress;
public loading(Context context) {
this.context = context;
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
progressBar.setProgress(0);
}
protected void onPostExecute(Integer result) {
Intent intent = new Intent(this.context, first.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
finish();
return;
}
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
preTime = System.currentTimeMillis();
}
protected void onProgressUpdate(Integer... values) {
progressBar.setProgress(values[0]);
}
#Override
synchronized protected Integer doInBackground(Void... arg0) {
int waited = 0;
while (waited < 3000) {
try {
// SystemClock.sleep(100);
this.wait(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
waited += 100;
}
return null;
}
}
Your doInBackground method needs to call publishProgress() in order for you to update the UI.
After the line waited += 100; add:
int progress = Math.round((float)waited / 3000 * 100);
publishProgress(progress);
Also, the signature of AsyncTask is wrong if you intend on using an integer to reflect your progress. The generic parameters are AsyncTask<Params, Progress, Result>, so in your case, you're not accepting any arguments, or returning any meaningful value from doInBackground, but, you do want to return an Integer to indicate progress. So, change your class declaration to match:
private class loading extends AsyncTask<Void, Integer, Integer>
{
//your implementation
}
You are not calling AsyncTask.publishProgress and that is why your onProgressUpdate method is never called.
And by the way, your class name loading brokes naming conventions, that's not a good practice.

Ideal way to cancel an executing AsyncTask

I am running remote audio-file-fetching and audio file playback operations in a background thread using AsyncTask. A Cancellable progress bar is shown for the time the fetch operation runs.
I want to cancel/abort the AsyncTask run when the user cancels (decides against) the operation. What is the ideal way to handle such a case?
Just discovered that AlertDialogs's boolean cancel(...); I've been using everywhere actually does nothing. Great.
So...
public class MyTask extends AsyncTask<Void, Void, Void> {
private volatile boolean running = true;
private final ProgressDialog progressDialog;
public MyTask(Context ctx) {
progressDialog = gimmeOne(ctx);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// actually could set running = false; right here, but I'll
// stick to contract.
cancel(true);
}
});
}
#Override
protected void onPreExecute() {
progressDialog.show();
}
#Override
protected void onCancelled() {
running = false;
}
#Override
protected Void doInBackground(Void... params) {
while (running) {
// does the hard work
}
return null;
}
// ...
}
If you're doing computations:
You have to check isCancelled() periodically.
If you're doing a HTTP request:
Save the instance of your HttpGet or HttpPost somewhere (eg. a public field).
After calling cancel, call request.abort(). This will cause IOException be thrown inside your doInBackground.
In my case, I had a connector class which I used in various AsyncTasks. To keep it simple, I added a new abortAllRequests method to that class and called this method directly after calling cancel.
The thing is that AsyncTask.cancel() call only calls the onCancel function in your task. This is where you want to handle the cancel request.
Here is a small task I use to trigger an update method
private class UpdateTask extends AsyncTask<Void, Void, Void> {
private boolean running = true;
#Override
protected void onCancelled() {
running = false;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
onUpdate();
}
#Override
protected Void doInBackground(Void... params) {
while(running) {
publishProgress();
}
return null;
}
}
Simple: don't use an AsyncTask. AsyncTask is designed for short operations that end quickly (tens of seconds) and therefore do not need to be canceled. "Audio file playback" does not qualify. You don't even need a background thread for ordinary audio file playback.
The only way to do it is by checking the value of the isCancelled() method and stopping playback when it returns true.
This is how I write my AsyncTask
the key point is add Thread.sleep(1);
#Override protected Integer doInBackground(String... params) {
Log.d(TAG, PRE + "url:" + params[0]);
Log.d(TAG, PRE + "file name:" + params[1]);
downloadPath = params[1];
int returnCode = SUCCESS;
FileOutputStream fos = null;
try {
URL url = new URL(params[0]);
File file = new File(params[1]);
fos = new FileOutputStream(file);
long startTime = System.currentTimeMillis();
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
byte[] data = new byte[10240];
int nFinishSize = 0;
while( bis.read(data, 0, 10240) != -1){
fos.write(data, 0, 10240);
nFinishSize += 10240;
**Thread.sleep( 1 ); // this make cancel method work**
this.publishProgress(nFinishSize);
}
data = null;
Log.d(TAG, "download ready in"
+ ((System.currentTimeMillis() - startTime) / 1000)
+ " sec");
} catch (IOException e) {
Log.d(TAG, PRE + "Error: " + e);
returnCode = FAIL;
} catch (Exception e){
e.printStackTrace();
} finally{
try {
if(fos != null)
fos.close();
} catch (IOException e) {
Log.d(TAG, PRE + "Error: " + e);
e.printStackTrace();
}
}
return returnCode;
}
Our global AsyncTask class variable
LongOperation LongOperationOdeme = new LongOperation();
And KEYCODE_BACK action which interrupt AsyncTask
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
LongOperationOdeme.cancel(true);
}
return super.onKeyDown(keyCode, event);
}
It works for me.
I don't like to force interrupt my async tasks with cancel(true) unnecessarily because they may have resources to be freed, such as closing sockets or file streams, writing data to the local database etc. On the other hand, I have faced situations in which the async task refuses to finish itself part of the time, for example sometimes when the main activity is being closed and I request the async task to finish from inside the activity's onPause() method. So it's not a matter of simply calling running = false. I have to go for a mixed solution: both call running = false, then giving the async task a few milliseconds to finish, and then call either cancel(false) or cancel(true).
if (backgroundTask != null) {
backgroundTask.requestTermination();
try {
Thread.sleep((int)(0.5 * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (backgroundTask.getStatus() != AsyncTask.Status.FINISHED) {
backgroundTask.cancel(false);
}
backgroundTask = null;
}
As a side result, after doInBackground() finishes, sometimes the onCancelled() method is called, and sometimes onPostExecute(). But at least the async task termination is guaranteed.
With reference to Yanchenko's answer on 29 April '10:
Using a 'while(running)' approach is neat when your code under 'doInBackground' has to be executed multiple times during every execution of the AsyncTask. If your code under 'doInBackground' has to be executed only once per execution of the AsyncTask, wrapping all your code under 'doInBackground' in a 'while(running)' loop will not stop the background code (background thread) from running when the AsyncTask itself is cancelled, because the 'while(running)' condition will only be evaluated once all the code inside the while loop has been executed at least once. You should thus either
(a.) break up your code under 'doInBackground' into multiple 'while(running)' blocks or
(b.) perform numerous 'isCancelled' checks throughout your 'doInBackground' code, as explained under "Cancelling a task" at https://developer.android.com/reference/android/os/AsyncTask.html.
For option (a.) one can thus modify Yanchenko's answer as follows:
public class MyTask extends AsyncTask<Void, Void, Void> {
private volatile boolean running = true;
//...
#Override
protected void onCancelled() {
running = false;
}
#Override
protected Void doInBackground(Void... params) {
// does the hard work
while (running) {
// part 1 of the hard work
}
while (running) {
// part 2 of the hard work
}
// ...
while (running) {
// part x of the hard work
}
return null;
}
// ...
For option (b.) your code in 'doInBackground' will look something like this:
public class MyTask extends AsyncTask<Void, Void, Void> {
//...
#Override
protected Void doInBackground(Void... params) {
// part 1 of the hard work
// ...
if (isCancelled()) {return null;}
// part 2 of the hard work
// ...
if (isCancelled()) {return null;}
// ...
// part x of the hard work
// ...
if (isCancelled()) {return null;}
}
// ...

Categories

Resources