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.
Related
I have a situation where I have multiple activities that deal with a single global list of objects.
From activity A, I can start an asynctask which sends an HTTP Get request to retrieve an XML message then parses the XML file into a series of objects.
My aim is to be able to refresh all views, only if the underlying data structure changes.
This should ideally mean that I can launch activity A, call an asynctask, move onto activity B, C D etc, and when the asynctask completes (no matter what activity I am on) the current view should be updated.
I've looked into broadcast listeners but I am not sure I am on the right direction with this, would it be possible for somebody to explain if this is possible?
Thanks
Since AsyncTask instances are dependent of the caller Activity, I think this is not the correct approach. In your case, as you need to recover the result within any Activity, I'd use an unbound Service so it might be accessed whenever you want, wherever you want.
You might also use a local BroadcastReceiver which would send a signal to all of your Activitys and, those registering the action that sent your AsyncTask/Service, would perform the necessary actions you may need. Be careful as if your Activity has not been started, obviously that Activity won't be able to process what you've sent since that receiver should be unregistered.
Just post a runnable to the handler of the current Activity.
Your activities can implement a common interface, where a function "updateUI" or whatever exists, and that way your runnable can be one line, and be agnostic as to the current active instance.
As you probably know the postexecute part of the asynctask runs on the UI thread of the activity that launches it. Since that activity may be dead, just post to the handler in the "doinbackground" part of the async task and keep postexecute blank.
interface Updateable{
public Handler getHandler();
public void updateUI();
}
From Async Thread
final Updateable curr_activity = ...
Handler handle = curr_activity.getHandler();
handle.post(new Runnable() {
#Override
public void run() {
curr_activity.updateUI();
}
});
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);
}
}
I'm working on an Android project that consists of several different Activities all associated with the same Application. We have some common tasks coded in the Application so that we don't have to duplicate them, and one of these tasks is regularly verifying a TCP connection to a dedicated server -- a heartbeat, I suppose.
If it's detected that the connection to the server is lost, I need to notify the user and I'd like to do this in a way that doesn't require me to check all the possible activities to see which is currently "on top".
Is there a way to call runOnUiThread() on whatever activity may be on the UI thread without knowing it explicitly??
Thanks,
R.
Regularly verifying a TCP connection
Sounds like this should be implemented using a service..
If the alert is very simple, and has minimal importance, I would suggest using a Toast.
If the alert is crucial, but it doesn't require the user's immediate attention, use a Notification.
If the alert demands immediate user attention, you should use a Dialog. You won't be able to start a dialog directly from a service or broadcast receiver because they don't have a window associated with them, but you can use an intent to start an activity on a new task. You can style the activity to be whatever you want. It could even look like a dialog box (or show a dialog box when it's started). Starting the activity in a new task will make sure the user can navigate back to whatever they're doing.
You can notify your Activities by sending Intent and registering BroadcastReceiver in each Activity you want to be notified.
service or application can be your context:
Intent i = new Intent("MY_ACTION_FROM_SERVICE_STRING");
context.sendBroadcast(i);
activity:
public class MyActivity extends Activity {
private ActivityBroadcastReceiver recvr;
public void onReceiveCommand() {
//do something
}
#Override
public void onCreate(Bundle b) {
super.onCreate(b);
recvr = new ActivityBroadcastReceiver(this);
this.registerReceiver(recvr,
new IntentFilter("MY_ACTION_FROM_SERVICE_STRING"));
}
}
receiver:
public class ActivityBroadcastReceiver extends BroadcastReceiver {
private MyActivity target;
public ActivityBroadcastReceiver(MyActivity target) {
this.target = target;
}
#Override
public void onReceive(Context context, Intent intent) {
target.onReceiveCommand();
}
}
One of the simple way (which I've adopted for my project too) is to create a base Activity class (preferably Abstracted) and then make your normal activity classes to extend it. By this, you may put a general piece of code in the abstracted class which may help you to detect currently visible activity.
Moreover, you may set a BroadcastReceiver in your base activity class which will always be ready to listen broadcasts regardless of setting it individually in your child activities and then set it to listen for broadcasts sent from your tcp thinggy.
Do not do any trickery. Implement Observer pattern, so any activity would register its listener in onResume() and unregister in onPause() and whatever will happend your Application object code needs just to tell about that to registered listeners, no matter what Activity they are in
I have an android widget which has a very simple function. The widget simply launches an activity when pressed, runs through the activity, pops a toast, and closes the activity.
The annoying thing is that when the widget is pressed on the home screen, the screen flickers as it opens and closes the activity. Is there any way to launch the activity from the background, to avoid this flicker? I'm kind of looking to do something similar to the ATK widget, which simply pops up a toast after closing all the background processes.
If it's possible to just run a single function in place of a PendingIntent, that would definitely work as well. Thanks!
I eventually did this by implementing a service instead of an activity. The service runs in the background and then stops itself once it has finished. The PendingIntent simply launches the service, using the getService() method of PendingIntent.
I know I'm very late, but I was having a similar problem and I didn't want to use a service.
If your activity is very quick, it is enough to modify your manifest and insert this into the activity your widget will be launching,
android:theme="#android:style/Theme.Translucent.NoTitleBar"
This way your activity will be transparent thus no flickering will be seen and, being it very quick it won't get in the way.
Please note that this may only be used if your activity is fast, otherwise it will result in a frozen effect.
I'm doing this kind of thing using Application class. You need to declare your own - e.g. MyApplication class (need to be declared in Android manifest) and during creation MyApplication just launch separate Thread:
public class MyApplication()
{
// only lazy initializations here!
public MyApplication()
{
super();
}
#Override
public void onCreate()
{
super.onCreate();
Log.d(TAG, "Starting MyApplication"+this.toString());
Thread myThread=new MyThread();
myThread.start();
}
}
So in the end you will have "background" application which doesn't contain any activities. Application will be alive while your thread is alive. From those thread you can start whatever you want - for instance popup window, toast or any activity - depending on what you want.
I Need some help here, I have a service which I can start or stop whenever I want and using the onStart() command to pass some extras using putExtras() from my activity
But I need some serious basic instructions on how to interact with the already created service.
Please don't refer me to another webpage which already have some implementations, just give me the needed code to interact from my UI activity to the service:
something like this:
public class myActivity extends Activity {
Object ReceivedObjectFromService;
onCreate()
{
some stuff here
myMethod()
}
public class myMethod()
{
//do some stuff with the ReceivedObjectFromService
//Don't know how to call this method from the service btw
}
please some help, I don't understand the tutorials on how to interact service to activity or viceversa
Interaction with already created service is no different to starting a brand new service. You just simply call startService() so your client code is no different.
Now, the part which is different is the service itself. In your service, onCreate() must start a background thread or a timer to carry on doing a work. onStart() will receive all startService cases and must in fact add the data it receives in the Intent to an internal list or queue and then in the timer's callback start processing from this queue.
Now you can pass any messages or data you want (even closing the service) using startService and passing data in the Intent that your service understands.
Hope this helps.