Android ASyncTask and service - android

How I can start my service in ASyncTask
for example
MyTask task = new MyTask();
startService(new Intent(MainActivity.this, MyService.class), task);
What is correct way to do this?
I want to tell service in which threads are executed

Quote from Android dev. :
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
I guess if you're not using directly startService, is that you want start it in a new thread, no ?
If so, you should do a new thread :
Thread t = new Thread(){
public void run(){
getApplicationContext().bindService(
new Intent(getApplicationContext(), YOURSERVICE.class),
serviceConnection,
Context.BIND_AUTO_CREATE
);
}
};
t.start();

Related

Android Bound Service in other thread

I have two Bounded Services, and some Activities that bind themselves to the services when they need it.
The problem is the performance of the app is slow when the activities write the information got from the services in the display.
Android's documentation says about the Stated Services:
Caution: A services runs in the same process as the application in
which it is declared and in the main thread of that application, by
default. So, if your service performs intensive or blocking operations
while the user interacts with an activity from the same application,
the service will slow down activity performance. To avoid impacting
application performance, you should start a new thread inside the
service.
But it says nothing about the Bound Services running in other threads. So i decided to start the services in this way:
private void startRunService()
{
final Intent intent = new Intent(this, RunService.class);
Thread thread = new Thread(new Runnable() {
public void run() {
startService(intent);
}
});
thread.start();
}
private void startLinkerRunService()
{
final Intent intent = new Intent(this, LinkerRunService.class);
Thread thread = new Thread(new Runnable() {
public void run() {
startService(intent);
}
});
thread.start();
}
So starting each service in a different service I got an unexpected improvement of the performance. But I'm not sure that it is a good idea.
Do you know if it has side effects?
Thanks in advance.

Implementing an android service for polling at regular intervals

What is the best way to implement an android Service (not IntentService) which polls a device using SNMP at regular intervals? I've tried implementing it with a Handler.postDelayed(Runnable) within onHandleIntent of IntentService. But later found it cannot be used in onHandleIntent() from this answer. My code just would not execute the runnable part.
make an IntentService not sleep until it executes a handler.postDelayed runnable
My code goes like:
public class MyPoller extends IntentService {
//Variable declarations
protected Handler handler;
public MyPoller() {
super("My service");
}
#Override
protected void onHandleIntent(Intent intent) {
.......
.......
runable = new Runnable() {
public void run() {
//My code here
handler.postDelayed(this, poll_interval);
}
};
handler.postDelayed(runable,poll_interval);
}
}
So I thought I could implement the same in a service, but I don't know how to implement this recurring task in a service also running it in a new thread. I found few answers demonstrating different ways of running recurring tasks in a new thread in a Service, but I'm confused.
Can someone suggest some way of implementing the same in a Service? It would be of great help. Thanks in advance.

how to stop Intent services in android

i have created one intent service. Now I want to stop that service from activity how to stop that service? My code is:
MyActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
Intent intent = new Intent(this, myService.class);
intent.putExtra("myHand", new Messenger(this.myHand));
startService(intent);
}
myService.java
public class myService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
String signal = intent.getAction();
if (signal != null && signal.equals("stop")) {
stopSelf();
} else {
t.schedule(new TimerTask() {System.out.println("print")}, 0, 10000);
}
}
}
to stop service on click of button
Intent in = new Intent(this, myService.class);
in.setAction("stop");
stopService(in);
can anybody help me to stop service?
From the docs for IntentService
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
In other words, you don't have to stop an IntentService - it will terminate itself when it has no more work to do.
EDIT:
Looking back at your code, it seems you don't wan't to stop the IntentService you want to stop the TimerTask???
t.schedule(new TimerTask() {System.out.println("print")}, 0, 10000);
I don't know what t is but I'm guessing it's a Timer. If that's the case it will be running with its own Thread and attempting to terminate the IntentService is pointless - kill the Timer instead.
Also, why are you using an IntentService to create any type of object which maintains its own thread of execution?
Now I want to stop that service from activity how to stop that
service?
IntentService stops itself, you shouldn't, you can't call stopSelf().
When all requests have been handled, the IntentService stops itself.
From what I know, IntentHandler creates a separate new thread, does its work, and kills itself.
So I don't think you need to explicitly stop it from an activity.

Accessing UI thread handler from a service

I am trying some thing new on Android for which I need to access the handler of the UI thread.
I know the following:
The UI thread has its own handler
and looper
Any message will be put
into the message queue of the UI
thread
The looper picks up the event
and passed it to the handler
The handler handles the message and
sends the specfic event to the UI
I want to have my service which has to get the UI thread handler and put a message into this handler.
So that this message will be processed and will be issued to the UI.
Here the service will be a normal service which will be started by some application.
I would like to know if this is possible.
If so please suggest some code snippets, so that I can try it.
Regards
Girish
This snippet of code constructs a Handler associated with the main (UI) thread:
Handler handler = new Handler(Looper.getMainLooper());
You can then post stuff for execution in the main (UI) thread like so:
handler.post(runnable_to_call_from_main_thread);
If the handler itself is created from the main (UI) thread the argument can be omitted for brevity:
Handler handler = new Handler();
The Android Dev Guide on processes and threads has more information.
Create a Messenger object attached to your Handler and pass that Messenger to the Service (e.g., in an Intent extra for startService()). The Service can then send a Message to the Handler via the Messenger. Here is a sample application demonstrating this.
I suggest trying following code:
new Handler(Looper.getMainLooper()).post(() -> {
//UI THREAD CODE HERE
});
At the moment I prefer using event bus library such as Otto for this kind of problem. Just subscribe the desired components (activity):
protected void onResume() {
super.onResume();
bus.register(this);
}
Then provide a callback method:
public void onTimeLeftEvent(TimeLeftEvent ev) {
// process event..
}
and then when your service execute a statement like this:
bus.post(new TimeLeftEvent(340));
That POJO will be passed to your above activity and all other subscribing components. Simple and elegant.
You can get values through broadcast receiver......as follows, First create your own IntentFilter as,
Intent intentFilter=new IntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");
Then create inner class BroadcastReceiver as,
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
/** Receives the broadcast that has been fired */
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction()=="YOUR_INTENT_FILTER"){
//HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW///////////
String receivedValue=intent.getStringExtra("KEY");
}
}
};
Now Register your Broadcast receiver in onResume() as,
registerReceiver(broadcastReceiver, intentFilter);
And finally Unregister BroadcastReceiver in onDestroy() as,
unregisterReceiver(broadcastReceiver);
Now the most important part...You need to fire the broadcast from wherever you need to send values..... so do as,
Intent i=new Intent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);
....cheers :)
In kotlin thats how you can do it
Let say if you want to show Toast message from service
val handler = Handler(Looper.getMainLooper())
handler.post {
Toast.makeText(context, "This is my message",Toast.LENGTH_LONG).show()
}
Solution:
Create a Handler with Looper from Main Thread : requestHandler
Create a Handler with Looper from Main Thread: responseHandler and override handleMessage method
post a Runnable task on requestHandler
Inside Runnable task, call sendMessage on responseHandler
This sendMessage result invocation of handleMessage in responseHandler.
Get attributes from the Message and process it, update UI
Sample code:
/* Handler from UI Thread to send request */
Handler requestHandler = new Handler(Looper.getMainLooper());
/* Handler from UI Thread to process messages */
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
/* Processing handleMessage */
Toast.makeText(MainActivity.this,
"Runnable completed with result:"+(String)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
for ( int i=0; i<10; i++) {
Runnable myRunnable = new Runnable() {
#Override
public void run() {
try {
/* Send an Event to UI Thread through message.
Add business logic and prepare message by
replacing example code */
String text = "" + (++rId);
Message msg = new Message();
msg.obj = text.toString();
responseHandler.sendMessage(msg);
System.out.println(text.toString());
} catch (Exception err) {
err.printStackTrace();
}
}
};
requestHandler.post(myRunnable);
}

Unexpected behavior of IntentService

I used IntentService in my code instead of Service because IntentService creates a thread for me in onHandleIntent(Intent intent), so I don't have to create a Thead myself in the code of my service.
I expected that two intents to the same IntentSerivce will execute in parallel because a thread is generated in IntentService for each invent. But my code turned out that the two intents executed in sequential way.
This is my IntentService code:
public class UpdateService extends IntentService {
public static final String TAG = "HelloTestIntentService";
public UpdateService() {
super("News UpdateService");
}
protected void onHandleIntent(Intent intent) {
String userAction = intent
.getStringExtra("userAction");
Log.v(TAG, "" + new Date() + ", In onHandleIntent for userAction = " + userAction + ", thread id = " + Thread.currentThread().getId());
if ("1".equals(userAction)) {
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
Log.e(TAG, "error", e);
}
Log.v(TAG, "" + new Date() + ", This thread is waked up.");
}
}
}
And the code call the service is below:
public class HelloTest extends Activity {
//#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent selectIntent = new Intent(this, UpdateService.class);
selectIntent.putExtra("userAction",
"1");
this.startService(selectIntent);
selectIntent = new Intent(this, UpdateService.class);
selectIntent.putExtra("userAction",
"2");
this.startService(selectIntent);
}
}
I saw this log message in the log:
V/HelloTestIntentService( 848): Wed May 05 14:59:37 PDT 2010, In onHandleIntent for userAction = 1, thread id = 8
D/dalvikvm( 609): GC freed 941 objects / 55672 bytes in 99ms
V/HelloTestIntentService( 848): Wed May 05 15:00:00 PDT 2010, This thread is waked up.
V/HelloTestIntentService( 848): Wed May 05 15:00:00 PDT 2010, In onHandleIntent for userAction = 2, thread id = 8
I/ActivityManager( 568): Stopping service: com.example.android/.UpdateService
The log shows that the second intent waited the first intent to finish and they are in the same thread.
It there anything I misunderstood of IntentService. To make two service intents execute in parallel, do I have to replace IntentService with service and start a thread myself in the service code?
Thanks.
The intent queuing is the whole point of using IntentService.
All requests to IntentService are handled on a single worker thread, and only one request will be processed at a time. If you want to do two tasks in parallel, I think you need to use Service and create threads for each task after Service starts.
As for AsyncTask, there's a thread pool for handling all of the tasks. If your task number exceeds thread pool size, some of these AsyncTasks will need to wait until a thread from the pool becomes available. However, the thread pool size changes in different platform versions.
Here's my test result:
Android 2.2: thread pool size = 5
Android 1.5: thread pool size = 1
As far as I know, The IntentService has one handler thread, and each intent queues in that thread. When all queued intents are done, the service exits. It does not create independent threads per intent. I don't know of any Service subclasses that work the way you are describing, you'd probably have to write your own.
I think what you want is an AsyncTask rather than either a Service or an IntentService. Or you could always just shoot from the hip by defining a runnable like this:
Runnable runnable = new Runnable() {
public void run() {
....
}
};
new Thread(runnable).start();
... for each of your tasks. Honestly, that may be easier than dealing this these Android helper classes.
Here is an example of using a Service instead of an IntentService, it might serve your purpose. http://developer.android.com/guide/topics/fundamentals/services.html#ExtendingIntentService

Categories

Resources