Two background service android - android

In my acivity, i need to run two background service.
main background service:
class loadingTask extends AsyncTask<Void, Void,Void> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
pd = ProgressDialog.show(context, "", "Chargement en cours..", true, false);
super.onPreExecute();
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.dismiss();
}
...
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
getxml = Util.CallWebService("");
return null;
}
}
Second background service.
class mloadingTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
SAXHelper sh = null;
try {
sh = new SAXHelper(urls[0]);
} catch (MalformedURLException e) {
e.printStackTrace();
}
sh.parseContent("");
return "";
}
protected void onPostExecute(String s) {
pd.dismiss();
}
}
In my onCreate() method I want to call the first background and when it finished loading the second background service starts. Part of my background service is as follows.
AsyncTask<Void, Void,Void> loadTask = new loadingTask().execute();
if(loadTask.getStatus()==AsyncTask.Status.FINISHED){
new mloadingTask().execute(getxml);
System.out.println("getxml: "+getxml);
}
However the second background service doesn't seem to start. i am not getting the a print also. I think I miss a step or android doesn't allow more than one background service in the same activity. A help please.

AsyncTask<Void, Void,Void> loadTask = new loadingTask().execute();
if(loadTask.getStatus()==AsyncTask.Status.FINISHED){
new mloadingTask().execute(getxml);
System.out.println("getxml: "+getxml);
}
there is a 99% chance that the if() block will never pass.
You first execute the first asyncTask named loadTask and RIGHT after check if it finished.
Small chance that it actually finishes by then.
The easy approach:
Use only one async task. You want to finish asyncTask 1 and then fire asyncTask 2, its exactly the same as having only one asyncTask doing both operations.
class loadingTask extends AsyncTask<Void, Void,Void> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
pd = ProgressDialog.show(context, "", "Chargement en cours..", true, false);
super.onPreExecute();
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.dismiss();
}
...
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
getxml = Util.CallWebService("");
SAXHelper sh = null;
try {
sh = new SAXHelper(urls[0]);
} catch (MalformedURLException e) {
e.printStackTrace();
}
sh.parseContent("");
return null;
}
}
The difficult approach:
How I solve this kind of thing is(our situation is different, but it should do)
Create an interface, with one method. for example:
public interface OnDataChangedListner {
void dataChanged(Class listener);
}
Then somewhere (i use my repository classes)
write a method to add and remove entires to a list of OnDataChangedListener interfaces
private ArrayList<OnDataChangedListner> mOnDataChangedListners;
public void addOnDataChangedListner(OnDataChangedListner onDataChangedListner){
synchronized (mOnDataChangedListners){
mOnDataChangedListners.add(onDataChangedListner);
}
}
public void removeOnDataChangedListner(OnDataChangedListner onyDataChangedListner){
if (mOnDataChangedListners != null){
synchronized (mOnDataChangedListners){
for (Iterator<OnDataChangedListner> it = mOnDataChangedListners.iterator(); it.hasNext();) {
OnDataChangedListner listener = it.next();
if (listener .equals(onDataChangedListner))
it.remove();
}
}
}
}
This might be overkill. But this example should help you with updating the UI while your tasks are running. A free extra! :))
With the above code in place, create an onDataChanged() method in the same class where u defined the add and remove listener methods.
In that code call a handler
// Need handler for callbacks to the UI thread
final static Handler mHandler = new Handler();
// Create runnable for posting
final Runnable mNotifyDataChanged = new Runnable() {
public void run() {
if (mOnDataChangedListners != null){
synchronized (mOnDataChangedListners){
for (Iterator<OnDataChangedListner> it = mOnDataChangedListners.iterator(); it.hasNext();) {
OnDataChangedListner listener = it.next();
if (listener != null)
listener.dataChanged(this.getClass());
else
it.remove();
}
}
}
}
};
/**
* will notify registerred delegates on the main (UI) thread
*/
public void notifyDataChanged(){
mHandler.post(mNotifyDataChanged);
}
Ok, so I ended up giving out an entire sample.
Where you place this code is upto you. But when you call notifyDataChanged() it will fire the handler, which in turn will loop trough all current registered listeners for this class
then in turn it will call the listeners datachanged method.
To make this all work, all you have to do is have a class implement the interface
call addOnDataChangedListener(this);
and implement the method provided in the interface.
Note that this is deffinetly not the easiest way to do things.
I don't know what the easiest way to do what you want is. I never have been in that situation before.
but you can execute the second task in the implemented method. Should work..

AsyncTask is Asynchronous as its name suggest. You need to call your 2nd AsyncTask in onPostExecute of your 1st AsyncTask
OR
Loop and wait till AsyncTask is finished in your activity, but it may take more time and you can get Application Not Responding message.
As soon as you call execute() method, control comes to next statement which loadTask.getStatus(). As task is just started, loadTask.getStatus() will not return FINISH and your 2nd task is never getting executed.

Related

Android Async not working

I have created an AsyncTask. I want to pair with a bluetooth device, and only after pairing it should go to next activity. My code is
public class YourTask extends AsyncTask<String, Void, Void>
{
public BluetoothDevice d;
#Override
protected Void doInBackground(String... urls)
{
//pairDevice(d);
return null;
}
public void onPreExecute()
{
pairDevice(d);
}
#Override
protected void onPostExecute(Void result)
{
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
CharSequence text = "Pairing";
Toast toast = Toast.makeText(context, text, duration);
toast.show();
startActivity(new Intent(NewDeviceActivity.this,DevicesActivity.class));
finish();
}
}
void pairDevice(BluetoothDevice device) {
try {
Method m = device.getClass()
.getMethod("createBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
The onPostExecute function gets executed even before pairDevice function has finished. Please help
The onPostExecute() method gets triggered after the tasks in doInBackground() have been completed. In your example you are not executing any tasks in doInBackground(), resulting in onPostExecute() to be called immediately. Move your method pairDevice(BluetoothDevice device) into the doInBackground() method and it should work.
Background Long operations should be done only in doInBackground method. This is the actual flow.
#Override
public void onPreExecute()
{
// this executes before Background operation starts
// here you can start showing ProgressBar to let the users know that it's still doing the work and you can dismiss in onPostExecute
}
#Override
protected Void doInBackground(String... urls)
{
// here you should do the long operation
return null;
}
#Override
protected void onPostExecute(Void result)
{
// here you can update the UI or move to other activity after long task has been done
}
The problem is, you are trying to run Background operation in onPreExecute.
public void onPreExecute()
{
pairDevice(d);
}
Just move the pairDevice(d) method to doInBackground method which is not correct.

Android Refreshing Service after AsyncTask

I am trying to re-initiate the entire function of download and uppdate service when an AsyncTask in my activity is being called but I am not sure if I am doing something wrong. Currently, I have a refresh button that initiates the AsyncTask:
Refresh function that initiates AsyncTask:
final ImageView refreshBtn= (ImageView) findViewById(R.id.spin_refresh);
Log.i("RootActivity:setupHeader","******ImageView refreshBtn******");
//Listening to Button Click by User
refreshBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("RootActivity:setupHeader","******OnClick,Call RefreshTask******");
//CALL ON THE CLASS OF REFRESHTASK ASYNCTASK
RefreshTask refreshtask = new RefreshTask();
refreshtask.execute();
}
});
Once my refresh function is called, it will call onto the refreshtask within my activity:
public class RefreshTask extends AsyncTask <Void,Integer,Long> implements Observer{
// SET THE PARAMETERS FOR REFRESHTASK IN ASYNCTASK: PRE-EXECUTION, PROGRESS UPDATES & POST-EXECUTION
private Context context=null;
private DownloadService callback =null;
protected boolean exitAsync = false;
public static Hashtable<String, Download> downloadList;
final public static String PATH = "/sdcard/DCIM/100MEDIA/";
private static final Long START_STICKY = null;
Intent intent;
ListView lv;
RelativeLayout rl;
protected String dSResponse = null;
public void UIThreadProgress(Context context, DownloadService callback) {
this.context = context;
this.DownloadService = DownloadService;
}
//PROCESS IN CALLING THE DOWNLIST WHILE IN BACKGROUND
protected Long doInBackground(Void...params){
// TODO Auto-generated method stub
Log.i("----------RefreshAsyncTask----------", "doInBackground");
try {
// ====================DownloadService
Thread.sleep(10000);
while (this.callback.condition())
Intent i= new Intent(context.this, UpdateService.class);
Intent I= new Intent(context.this,DownloadService.class);
// potentially add data to the intent
context.this.startService(i);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}while (!exitAsync);
return START_STICKY;
}
#Override
public void update(Observable observable, Object data) {
// TODO Auto-generated method stub
//UpdateServiceStatus
}
//HANDLES EVENTS ON THE UI-POST-EXECUTE
#Override
protected void onPostExecute(Long result){
super.onPostExecute(result);
lv.findViewById(R.id.spin_refresh).setVisibility(View.VISIBLE);
Log.i("----------RefreshAsyncTask----------", "onPostExecute");
//GIVE FEEDBACK ON THE USER INTERFACE
Toast.makeText(context, "Your document has been refreshed and contains the updated documents!", Toast.LENGTH_LONG).show();
// After the process in doInBackground has been completed
}
}
Please help, I am trying to re-instantiate the download and update service when AsyncTask is being called.
I can't understand why you start a service inside a thread. You should start a thread in a service instead. Check Local Service sample in this link:
http://developer.android.com/reference/android/app/Service.html
In your onClickListener just unbind service and bind it again. It will refresh your service. In onCreate method of your service start your download or update in a thread.
Note: It is better to use another thread mechanism for network service. AsyncTask is good for short-lived operations.
#Override
protected void onPostExecute(Long result){
super.onPostExecute(result);
lv.findViewById(R.id.spin_refresh).setVisibility(View.VISIBLE);
Log.i("----------RefreshAsyncTask----------", "onPostExecute");
//GIVE FEEDBACK ON THE USER INTERFACE
Toast.makeText(context, "Your document has been refreshed and contains the updated documents!", Toast.LENGTH_LONG).show();
RefreshTask refreshtask = new RefreshTask();
refreshtask.execute();
// After the process in doInBackground has been completed
}

runOnUiThread is not running in AsyncTask

I'm coding a program which fetches the data from MySql from server (using JSON) and it updates the UI accordingly,
I'm fetching two types of data using AsyncTask from Server
1) Bubble Answers
2) Comments
The parseBubbleAnswers method successfully runs and Updates UI,
but parseComments class which is AsyncTask, and which call parseComments method in doInBackground, is not running runOnUiThread(new Runnable() { run() });
Can anyone help me in solving this
Here is my code :
public class FetchServer extends Activity
{
protected void onCreate(Bundle savedInstanceState)
{
String photoId = "1"; // photo id for which the data is fetched
checkBubbleData(photoId); // which call AsyncTask - 2 differnt calls
}
public void checkBubbleData(String photoId)
{
new parseBubbleAnswers().execute(photoId); // to fetch bubble answers
new parseComments().execute(photoId); // to fetch comments
}
class parseBubbleAnswers extends AsyncTask<String, Integer,String>
{
#Override
protected String doInBackground(String... params)
{
// TODO Auto-generated method stub
Looper.prepare();
parseBubbleAnswers(); // which has runOnUiThread(new Runnable() which updates (successfully !) the UI
return null;
}
}
class parseComments extends AsyncTask<String, Integer,String>
{
#Override
protected String doInBackground(String... params)
{
// TODO Auto-generated method stub
Looper.prepare();
String parseComReturn = parseComments();
if(parseComReturn=="end")
{
commentBuilder(); // which will update UI after fetch data by parseComments() method
}
}
}
public void commentBuilder()
{
runOnUiThread(new Runnable() // while debugging, it comes here, on Step Over it stick for 2 times and then move at the end of method without error
{
public void run()
{
// update UI code
}
});
}
}
Try this way :
First create one Handler :
Handler mHandler = new Handler();
Change this,
public void commentBuilder()
{
runOnUiThread(new Runnable() // while debugging, it comes here, on Step Over it stick for 2 times and then move at the end of method without error
{
public void run()
{
// update UI code
}
});
}
With,
public void commentBuilder()
{
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (isRunning) {
try {
// Thread.sleep(10000);
mHandler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
// Write your code here to update the UI.
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
}
Stop thread by this once you are done with UI,
isRunning = false;
EDIT :
Try to Use Async Task in this way :
class parseComments extends AsyncTask<String, Integer,String>
{
protected String doInBackground(String... params) {
String parseComReturn = parseComments();
return parseComReturn;
}
protected void onPostExecute(String result) {
if(result.equals("end"))
{
commentBuilder();
}
}
}
Thanks.
runOnUiThread is a method of Activity, AsyncTask has no reference to Activity.
however, AsyncTask already runs on the UI thread and was designed to do exactly that.
just deal with the UI changes in onPostExecute.
I faced the similar issue.
Just pass the reference of the Activity class to the parseComments class.
class parseComments extends AsyncTask<String, Integer,String>{
Activity activity;
public parseComments(Activity activity){
this.activity = activity;
}
}
After that you can use runOnUiThread as
activity.runOnUiThread(new Runnable(){
#Override
public void run(){
}
});
It will only work with Activity class. Not Context class.

Android: auto start an app and exit when finish in onCreate()

I want to make a test app, that when called, execute a few lines of code, and then exit automatically. I want all these done within onCreate().
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("onCreate()");
try {
initSocket(); //connect to server
} catch (IOException e) {
e.printStackTrace();
}
new Thread(new AudioRecordThread()).start();
}
The problem is, how can I exit the app in onCreate()? I tried "this.finish()" but didn't work.
Any one can help?
EDIT
I agree that the problem may be caused by thread. Will post my answer when solved.
I think the Problem is your AudioRecordThread which shares the same Process with your App. You could definetly call this.finish() inside onCreate (done this often, never had problems), but that doesn't mean neccesarily that your AudioRecordThread gets killed the same time as your Activity. So without further Information about your Thread, and if it should stay alive on finish of your Activity I cannot give you any advise. If You want that Thread to be alive, after your Activity finishes, a Service is the way to go.
try
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("onCreate()");
try {
initSocket(); //connect to server
} catch (IOException e) {
e.printStackTrace();
}
new Thread(new AudioRecordThread()).start();
finish();
}
Perhaps what you are trying to do is a service?
Have a look here: http://developer.android.com/reference/android/app/Service.html
try this one
finish is working in onCreate() & onResume().. there is another problem in your code
#Override
protected void onResume()
{
super.onResume();
finish();
}
You can use an AsynTask in your activity, juste put this class in the Same file of your activity
=> In onPostExecute() methode you will test if your handling is finished to close your activity.
class MyAsynTask extends AsyncTask<Void, Integer, Boolean> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// Init your variables, in my case it's my Progress Bar
myprogress = new ProgressDialog(mcontext);
myprogress.setTitle("Update");
myprogress.setMessage("Update running ....");
myprogress.show();
}
#Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
boolean test = false;
int j = 0;
for (int i = 0; i < 50; i++) {
j = i + 10;
publishProgress(i);
// Your implemention code to connect to the server
if (i == 49)
test = true;
}
return test;
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
myprogress.setProgress(values[0]);
}
#Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (myprogress.isShowing())
myprogress.dismiss();
if (result){
Toast.makeText(mcontext, "I Finished",Toast.LENGTH_SHORT).show();
yourActivity.this.finish();
}
}
}

How to run the same asynctask more than once?

I have my asyncTask run when the activity first starts, then if network connectivity is not available then i have a refresh button that tries to run the asyncTask to try again. But i get a debug error saying this..
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): FATAL EXCEPTION: main
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once)
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:541)
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at android.os.AsyncTask.execute(AsyncTask.java:499)
07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at com.fttech.gameIT.MainMenu$1.onClick(MainMenu.java:90)
Is there anyway to run this twice?
Just create another instance and execute it.
Just like threads, AsyncTasks can't be reused. You have to create a new instance every time you want to run one.
You can never execute a thread again, not in Java, not in any other language, once the thread is done with the run() method, you cannot restart it, which is why you are getting the IllegalStateException.
You can however still call the methods on that thread but they will run on the thread that is calling them NOT on a different thread. Therefore you will have to create a new one.
You cannot run same instance of an AsyncTask more than once.
Let's assume you have an AsyncTask named MyAsyncTaks and you intend to do something like this,
MyAsyncTask myAsyncTask = new MyAsyncTaks();
myAsyncTask.execute(); // Works as expected
.
.
.
.
myAsyncTask.execute(); // This will throw you exception
The reason for this is, a thread once finishes its 'run' method, cannot be assigned another task. Here, on the first invocation of execute(), your AsyncTask started running and
after doing its job, the thread comes out of run. Naturally, next invocation of execute() will throw you exception.
The simplest way to run this more than once is to create a new instance of MyAsyncTaks and call execute on that.
MyAsyncTask myAsyncTask = new MyAsyncTaks();
myAsyncTask.execute(); // Works as expected
.
.
.
MyAsyncTask myAsyncTask2 = new MyAsyncTaks();
myAsyncTask2.execute(); // Works as expected
Though its not needed to be mentioned here, one must be aware that post Android SDK version Honeycomb, if your run more than one AsyncTask at once, they actually run
sequentially. If you want to run them parallally, use executeOnExecutor instead.
Just make a new call like new asyncTask().execute(); You must create a new object to restart that task.
I just create the asynctask then create a runnable that creates new instances of the asynctask. Then you can submit your runnable over and over again to the handler.
class MyAsyncTask extends AsyncTask<String, Void, String>{ ...}
Runnable myRunner = new Runnable(){
public void run() {
new MyAsyncTask ().execute(...);
}};
myHandler.post(myRunner);
This solved my problem:
public class MainActivity extends AnimationActivity {
MyAsyncTasks asyncTasks = new MyAsyncTasks();
#BindView(R.id.refresh_btn)
Button refreshBtn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUnbinder(ButterKnife.bind(this)); // ButterKnife usage
syncTasks(); // run asyncTasks on activity start
refreshBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
syncTasks(); // run asyncTasks on button click
}
});
}
private void syncTasks() {
try {
if (asyncTasks.getStatus() != AsyncTask.Status.RUNNING){ // check if asyncTasks is running
asyncTasks.cancel(true); // asyncTasks not running => cancel it
asyncTasks = new MyAsyncTasks(); // reset task
asyncTasks.execute(); // execute new task (the same task)
}
} catch (Exception e) {
e.printStackTrace();
Log.e("MainActivity_TSK", "Error: "+e.toString());
}
}
}
You can do it like this :
private MyAsyncTask createAsyncTask(){
if (myAsyncTask == null){
return myAsyncTask = new MyAsyncTask();
}
myAsyncTask.cancel(true);
return myAsyncTask = new MyAsyncTask();
}
and then you can use it :
createAsyncTask().execute();
this make a new instance of your background task everytime.
Async tsk only run once as the Exceptions says the task has already been executed..
So you just have to make a new instance of async and then call .execute();
in order to run it again .. thank you
I created an Arraylist of type ProgressUpdater(Name of class which extends AsyncTask) and added the instances into it(in the onClick of a button). So you can execute and cancel these task when needed.
public class MainActivity extends Activity {
ProgressBar progress;
ProgressUpdater task;
ArrayList<ProgressUpdater> pu = new ArrayList<MainActivity.ProgressUpdater>();
int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = (ProgressBar) findViewById(R.id.progress);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn:
task = new ProgressUpdater();
pu.add(task);
count++;
pu.get(count - 1).execute(0);
System.out.println("task" + task);
// task.execute(10);
break;
case R.id.btnCancel:
if (count >= 0) {
pu.get(count - 1).cancel(true);
pu.remove(count - 1);
count--;
}
// task.cancel(true);
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class ProgressUpdater extends AsyncTask<Integer, Integer, Void> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progress = (ProgressBar) findViewById(R.id.progress);
progress.setMax(100);
}
#Override
protected Void doInBackground(Integer... params) {
// TODO Auto-generated method stub
int start = params[0];
for (int i = start; i <= 100; i++) {
try {
boolean cancelled = isCancelled();
if (!cancelled) {
publishProgress(i);
SystemClock.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.v("Progress", "Finished");
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
progress.setMax(0);
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
progress.setProgress(values[0]);
}
}
}
in your MainActivity you can put so this:
LeoAsyncTask leoAsyncTaskGeneric;
public void onClick_AsyncTask(View view) {
LeoAsyncTask leoAsyncTaskInner = new LeoAsyncTask();
leoAsyncTaskInner.execute();
leoAsyncTaskGeneric=leoAsyncTaskInner;
}
/**if you create a space in memory of your AsyncTask class as a generic, then you can create an instance of that same class within the onClick method, and there the equals, so every time you press onClick you will be using a new instance of the Class AsyncTask, it will not give you problems
*/
You could cancel your asyncTask when you press the button and then execute it again.
Inside OnClic method:
asyncTask.cancel();
AsyncTask asyncTask = new AsyncTask();
asyncTask.execute();
#coder_For_Life22 I think am late for the answer ,anyway you can do like
#Override
protected void onPostExecute(Void a) {
myAsyncTask=new MyAsyncTask();
}
in order to start a new AsyncTask after execution :)

Categories

Resources