I m new in android, I'm not much aware about services.i have an activity class with a UI, i want to make this activity class runs in background, when i click the back button. how to make my activity runs in background like a service, plz help me..
You cannot really run an Activity on background! When an activity is not on foreground it gets to onStop and then the system could terminate it, to release resources, by onDestroy method! see Activity Lifecycle
In order to run on background you need to create a Service or IntentService
Checkout android javadoc about Services here and here or IntentService
and here is a third-party Android Service Tutorial
Edit: you may also need a communication between your service and your activity so you can get through that: Example: Communication between Activity and Service using Messaging
If you simply want your activity runs in back Try using
moveTaskToBack(true);
It seems like you want to run an activity in background when it quits. However, activity can't be run unless it's on foreground.
In order to achieve what you want, in onPause(), you should start a service to continue the work in activity. onPause() will be called when you click the back button. In onPause, just save the current state, and transfer the job to a service. The service will run in the background when your activity is not on foreground.
When you return to your activity later, do something in the onResume() to transfer the service 's job to your activity again.
You should read the developer guide on Threads: http://developer.android.com/guide/components/processes-and-threads.html
Specifically the function doInBackground()
Example from page:
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
Related
I want to specify an activity to be the loading activity for my app for some async Tasks .
it will be launched during in preExecute and will be finished in postExecute how to do that ?
#Override
protected void onPreExecute()
{
startActivity(new Intent(SearchActivity.this,LoadingActivity.class));
}
#Override
protected void onPostExecute(String result)
{
// i want to finish loading activity here.
}
That's just not how Android works.
There is always one Activity active at a time, and when you start an AsyncTask, you do so in the context of the current Activity.
So, while you technically could start an activity from the AsyncTask, it's parent context (the Activity that started the AsyncTask) would become inactive. The AsyncTask would continue to run (this is actually a big problem with AsyncTasks), but would likely crash - and even if not, the behavior would be undefined.
Shubham Nandanwar's answer looks like it should work, but is not the correct way to approach this. You should reconsider what you are trying to do in the context of the way that Activities and their lifecycles are supposed to work.
I'd suggest simply launching the Activity that you desire, and then use an AsyncTask in that activity to do whatever work needs to be done, and finish the activity from the activity itself when the work is done.
Better yet, find a better way to do background processing (e.g. RxJava), and do away with the AsyncTask.
In my application i start an service from a activity using startService command. This service is used for uploading file so it will take time.
So what i want is my Activity should be finished and srvice should keep on doing its work. For this purpose after calling startService() i call the activity finish also.
Because of this my service stops in between abruptly while if i dont call finish of activity everytihng works fine. I want to know how to make it possible so that service keep doing its work while Activity (who started this service) is finished.
Thanks in advance for help.
You should do your uploads via IntentService because:
•The Service runs in background but it runs on the Main Thread of the application.
•The IntentService runs on a separate worker thread. so it runs your codes even when your application's Activity isn't open
Use something like this:
package com.example.test;
public class MyService extends IntentService{
public DownloadService(){
super("DownloadService");
}
#Override
protected void onHandleIntent(Intent arg0){
// Here is your codes
}
and here is a good sample ;-)
Hi I'm implementing a custom asynctaskloader to load data in the background, and I need the loading process to run even if the user navigated out of the application. The problem is, once the user presses the menu button for example the loader onStopLoading() is called and then the loadInbackgroud() is called to restart the loading process.
Any ideas how can I prevent the loader to restart the loading process every time I navigate out of the program or turn of the screen given that during the loading process I acquire a partial wake lock.
P.S: The loader is attached to a fragment and the fragment RetainInstance is set to true.
Thanks in advance.
Have you considered using an IntentService instead of an AsyncTask?
An IntentService is a component which runs in the background and is not bound to the lifecycle of an activity, thus will not be affected when a fragment/activity is paused/restarted/destroyed. You can still publish progress/results/failures to activity or fragment-based listeners using a ResultReceiver.
A very basic code sample:
public class MyService extends IntentService
{
public MyService()
{
super("MyService");
}
#Override
protected void onHandleIntent(Intent intent)
{
// Perform your loading here ...
publishOutcome("Success");
}
private void publishOutcome(String outcome)
{
Bundle outcomeData = new Bundle();
outcomeData.putString(OUTCOME, outcome);
receiver.send(MY_OUTCOME, outcomeData );
}
}
For a more detailed discussion on AsyncTask vs IntentService have a look at this StackOverflow question.
I noticed that sometimes Async task does not work properly , Actually its doInBackground() method does not get called , this happens mostly when any service run in background for that activity.
For Example , when music runs in background with service, the Async task does not parse XML in background as its doInBackground does not work that time and the progress Dialog or progressBar kept spinning.
I read in few articles that AsyncTask.THREAD_POOL_EXECUTOR can help in these issues like :
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new Test().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new Test().execute();
}
but that did not help in my case. Having the same issue after the above implmentation.
Here I am giving just a bit of my sample code to understand what I am doing::
public class TestAct extends Activity {
ImageButton play,forward,backward;
private ListView mList;
// many more variables
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
//binding the service here
// start service is called
init();
}
private void init(){
play=(ImageButton)findViewById(R.id.playBtn);
forward=(ImageButton)findViewById(R.id.forward);
backward=(ImageButton)findViewById(R.id.backward);
mList=(ListView)findViewById(R.id.list);
new GetData().execute();
play.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// calling the play() method of ServiceConnection here
}
});
// adding header to Listview
// other code and click listeners
}
class GetData extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
// starting the progress Bar
// initializing the Arraylist,Maps etc
}
#Override
protected Void doInBackground(Void... params) {
//parsing the XML here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// stop the ProgressBar
// Updating my UI here
// setting Adapter for ListView
}
}
}
This works fine generally but hangs when Service runs in backgound (I mean when music is playing in back).
I am not getting the exact reason behind this problem of Async task.
Will mannual thread implementation help in this case ...??
Well, I think the problem is because "Service runs in main thread so when it runs, it blocks my AsyncTask to run"... So I think If we can run Service in background thread then that can help . Thats why I tried IntentService for running service in separate thread but I am in doubt... if IntentService can run for indefinite time similar to Service ... and Also IntentService blocks AsyncTask few times.
So I dont't think its 100% perfect solutions for this kind of problem.
Can anyone help me to sort out this problem and understand the complete scenario.
Thanks in advance.
Sometimes you will want more control over your service's lifecycle than what IntentService gives you, in those cases you can just create a thread in the service and run your background code in that. Actually, to be more specific, create a HandlerThread which includes a Looper so you can use the standard android method for communication (messages) between your main thread and the background thread.
Answered here
I think the problem is starting another GetData AsyncTask before the previous one has been finished. Before executing another task make sure that previous one is complete. To do this use following code:
// make sure we don't collide with another pending AsyncTask
if (getDataTask == null || getDataTask.getStatus() == AsyncTask.Status.FINISHED || getDataTask.isCancelled()) {
getDataTask= new GetData();
getDataTask.execute();
}
Also make sure that you have a reference for running tasks. You can use subclass of Application class for doing this while your application is running or override onSaveInstanceState(Bundle outState)
and receive a reference to it in onCreate(Bundle savedInstanceState).
Read all the problem and Answers which has been posted here. correct me if i am wrong your scenario is you are parsing the xml and getting the list of songs and when user select any song you want that to be played with service right?
if the Scenario is correct then we can implement it in the much simpler way.
In the Activity, onResume() method parse the XML file and get the list of songs and update the list view(do not start anything related to service here)
when user click on the song then pass the particular key/string to the service with intent and start the service
In the service's OnStartCommand() method get the identifier and start the song as with normal media APIs
That will actually do the work for you.
Regarding the problem of
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new Test().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new Test().execute();
}
This is for different behavior of the AsyncTask on Different version of the Android.
Looking at your code what is being done is in the Activity you are initializing the service hence the service is running in the background without doing anything fruitful.
and when user click on play you are calling play function of service which created problme here.
so to call the function of service from Activity you should right AIDL which you have not mentioned. and if you have wrote so it should be perfect.
but here recommendation is pass the song id to service and it should play from service should not call Service's function in activity.
if you want to update the Song List in the onResume of the activity then you must write AIDL and accomplish the scenario
Hope this will help.
I noticed that sometimes Async task does not work properly , Actually
its doInBackground() method does not get called , this happens mostly
You know that there is a limit of AsyncTasks that can be executed at a time? I had once an issue where a task did't start/work properly and this was because I exceeded that number. Check Android AsyncTask threads limits? for more on that topic.
when any service run in background for that activity. For Example ,
when music runs in background with service, the Async task does not
parse XML in background as its doInBackground does not work that time
and the progress Dialog or progressBar kept spinning.
Have you checked the possibilities of dead locks (in particular, if you're using wait() and notify())?
Well, I think the problem is because "Service runs in main thread so
when it runs, it blocks my AsyncTask to run"... So I think If we can
run Service in background thread then that can help . Thats why I
The things you are going to do in a service should run in an own thread anyway. That way you can be sure that nothing is going to be blocked. If you have something to populate you could use a receiver, for instance.
Hope I could help a bit ...
Here is a hint, How I finally solved my Problem ::
1) I used IntentService instead of Service as Service runs in mainThread while IntentService runs in a separate Thread than mainThread to make sure that my background Service does not effect my current task . Also , I am using AIDL for communication between my UI and background Thread (this was already working for Service , so nothing new in this part).
2) I used painless thread instead of AsyncTask, I interrupt the thread in onDestroy() method to make sure that the Thread does continue indefinitely.
App seems to perform much better than Earlier now.
Hope this will help others too :)
Per the Threading Rules section of the Android Developer AsyncTask document, the AsyncTask has to be created and launched on the UI thread, so if you are launching it from a background thread in a Service, that would account for the faulty behavior.
http://developer.android.com/reference/android/os/AsyncTask.html
You really shouldn't be using AsyncTasks in general :) There is a pretty good explanation here . Think about what will happen if the user rotates the device, while your task is running. The Activity is recreated, but the task runs in the background and holds a reference to the "old" activity. There are ways to get around this, and they are surely still some cases where an AsyncTasks is the correct approach.
However, your really should consider switching to a Loader or (if you feel adventurous) try RoboSpice :)
I want to use AsyncTask to call another application. I have a main app that does its own thing but when I launch it, it does an AsyncTask to call a "messages" application which checks to see if there are any unread messages and then displays a notification in the status bar.
However, when I called execute(), the messages application jumps to the front and I have to press the back button to get to my main application.
Code is as follows (my main application)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MessageUpdate update = new MessageUpdate(this);
System.out.println("Calling Update");
update.execute(null);
....
My AsyncTask:
public class MessageUpdate extends AsyncTask{
Context ctx;
public MessageUpdate(Context ctx){
this.ctx = ctx;
}
#Override
protected Object doInBackground(Object... params) {
Intent notificationIntent = new Intent();
notificationIntent.setClassName("com.test.messages", "com.test.messages.MessageCheck");
ctx.startActivity(notificationIntent);
return null;
}
}
Can anyone tell my why the MessagesCheck jumps to the front and how to stop it? Or if what I'm doing is even feasible?
As others have pointed out, a service is the way to go. However, if you use bindService() the service will only last as long as it's bound.
Just to clarify some of the issues:
Using startActivity to communicate with a background task is not what you want, as an Activity is a user interface component, which will come to the front when activated.
The suggestion is that you add a service to your "messages" application, not the main application.
You can then communicate with the "messages" application from the main application by binding to the service. If you do this (using bindService), the service will not run indefinitely.
The details of how to do this are here.
You could do all this without an AsyncTask, however it may help to avoid blocking the UI thread if the service takes significant time to do its job. Alternatively, your service could use a background thread of its own to check for messages and post the notification.
Have you considered make com.test.messages.MessageCheck a Service not an Activity, then calling startService(...)
You are starting an Activity in your ASyncTask, so your current Activity is brought to the back.
In order to prevent that, you'll have to use a different way to check if there is a new message. You could either do that verification in your ASyncTask and display the notification from it, or use a Service.