ANR when I am starting a service - android

I am using a service to download heavy files from the web.but when the files are being downloaded I am unable to interact with the app. What is the best way for this .
I am downloading files that are about 10 MB and I want the user to interact with app while the files are downloaded
Please find the my service code.
public static class MyService extends Service {
#Override
public IBinder onBind(Intent arg0) {
return null;
}
public MyService(){
super();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
System.out.println("service started");
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
//Toast.makeText(Description.this, "Downloading content...", Toast.LENGTH_LONG);
GetShowsInfo(downloadEpisodeMedia(episode_id));
RequestDownloads();
File cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"Folder Name");
listf(cacheDir,files);
mediaPlayerflag=true;
//progressBarLayout.setVisibility(LinearLayout.VISIBLE);
nowPlayingEpisode=categoryName;
//NowPlayingEpisode.setText("Now Playing "+episodeArrayList.get(position).getName());
textView_MediaPlayer.setText(nowPlayingEpisode);
//textView_EpisodeCount.setText(episodeCount);
playOnebyOneMedia();
// StoreInfo(GetCategories());
//StoreDescription(GetDescription());
return START_STICKY;
}
#Override
public void onDestroy() {
System.out.println("service stopped");
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}

I think you are performing very large operations on the UI thread like downloading files..ANR comes when the UI thread perform the long running operations..try to do it with using AsynchTask or threads..then you can avoid ANR..
check this link for download file in AsynchTask example..AsynckTask example

You can use IntentService instead of Service. IntentService uses a separate thread to handle intents. So it wont block your main thread. onStartCommand method of your service runs in main thread and blocks it for too long time and causes ANR.

Related

background service for Notification is not working

I tried to use the following code trigger toast as background service but it gets executed for 20 times, it was not working till 100. With thread it is not working gives error.
Felt service get destroyed.
How to trigger notification with 30 minutes difference as a background service, though app is closed,
I need to display Good morning, Good Afternoon, Good Evening and Good night as a Notification.
without any internet support.
Is following procedure not ok? I think so. How to do this?
import android.app.Service;
public class HelloService extends Service {
private static final String TAG = "HelloService";
int i=0;
private boolean isRunning = false;
#Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
Toast.makeText(this, " On create Hello Service Started", Toast.LENGTH_LONG).show();
isRunning = true;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
for (;i<100; i++) {
try {
// Thread.sleep(1000);
Toast.makeText(getApplicationContext(), "Hello Service On Loop"+i , Toast.LENGTH_LONG).show();
//
} catch (Exception e) {
}
}
//Stop service once it finishes its task
// i++;
stopSelf();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onDestroy() {
isRunning = false;
Log.i(TAG, "Service onDestroy");
}
}
onStartCommand() is called on the main (UI) thread. If you execute a loop inside onStartCommand(), Android will kill the process after about 30 seconds with an ANR (Application Not Responding) because you cannot block the main (UI) thread.
You can do what you want either using AlarmManager to set a timer that will start your Service or trigger a BroadcastReceiver at certain times, or you can post a Runnable to a Handler in onStartCommand() with a certain delay and do whatever you want in the Runnable, or you can start a background thread in onStartCommand() and the background thread can loop and sleep or whatever and then do what you want.
In any case, you cannot show a Toast every second. This will flood the UI with toasts and either Android will dump most of them (ignore them) or the UI will be so busy showing them that Android will kill your app due to ANR or the user will just uninstall your app!

Android Background Service and Thread

I am developing android application using rabbit mq pub/sub technology. I want to listen incoming message in android background service. Can I run thread in android background service ?
public class MessagingService extends Service {
private Thread subscribeThread;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
subscribeThread = new Thread(new Runnable() {
#Override
public void run() {
//Connecting to server and listen incoming message.
}
});
subscribeThread.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
subscribeThread.interrupt();
}
}
Yes you can run new thread in Android Service.
Please see note in documentation here: http://developer.android.com/guide/components/services.html
Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work.
Hope this will help you.

Stop the Service after the Vibrating the Phone in android?

I am trying to learn service in android.My goal is like that i will pass a LatLng Object to the service then service will do something with that and when the work will be finished then it will buzz the phone for sometime and stop.Finally the service will be finished.Now I have some query on that:
I will call the service from my app and user can close my app though
service is not finished.will service do the job initiated by my app or
it will also finish??
What i studied take me here that service will continue to execute and one thing i don't have to return anything back to activity who has initiated the service.I have written some code.Can anyone help me out??
public class MapService extends Service {
private boolean isRunning = false;
#Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
isRunning = true;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
//Creating new thread for my service
//Always write your long running tasks in a separate thread, to avoid ANR
new Thread(new Runnable() {
#Override
public void run() {
//here i will do my work
if(isRunning){
Log.i(TAG, "Service running");
}
}
//Stop service once it finishes its task
stopSelf();
}
}).start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onDestroy() {
isRunning = false;
Log.i(TAG, "Service onDestroy");
}
}
Will it work if user closes the app??
Yes this service will run even if user will close app.It is also possible if android system demands memory service will be stopped but it will restart again
as you have set your flag START_STICKY in your onStartCommand.
On Android KitKat and above(4.4+), the service will be stopped if user swipe kills the application and it won't be restarted by the system. See this discussion(1). If the application was stopped by Android system itself (for low resources), the service will be restarted after a while(use START_STICKY flag).
On Android 4.3 and below, service will be restarted irrespective of whether application was stopped by system or user(use START_STICKY flag).
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}

Always runs service in background on Android?

I am building an app which has a background service for continuously communicating with a Raspberry Pi.
I am making the service sticky(Service.START_STICKY) so that is will restart when it's killed by user or OS.
This works well for the first 30-40 minuten. After 30-40 minutes the services seems to be stopped.
Isn't there any way to avoid this problem? I know it's bad for the batterylife if there is service continiously runnnig in the background. The app is used in my own project to automate my room and is only used by me. So the batterylife isn't a problem.
public class RaspberryPiCommunication extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Do continuouswork here in a seperate thread
return Service.START_STICKY;
}
}
I also have another quetions about service:
If the service is started twice in the following example, will there be two instances of SomeObject() and is doSomWork() running twice in background?
public class RaspberryPiCommunication extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SomeObject obj = new SomeObject();
obj.doSomeWork();
return Service.START_STICKY;
}
}
Are you running the service on its own thread ? By default, A service runs on the main thread. For a long running task like this run it in a separate thread
Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work.
Service will run only in one Instance. onStartCommand() is called every time you start the service.
http://developer.android.com/guide/components/services.html#StartingAService
Here is required piece of code.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
handler.postDelayed(runnable, 1000 );// 1000 - Milliseconds
if (appContext == null) {
appContext = getBaseContext();
}
Toast.makeText(appContext, "Services Started", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
Runnable runnable = new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
DoBackgroundTasks();
handler.postDelayed(this, 1000 ); // 1000 - Milliseconds
}
};
void DoBackgroundTasks()
{
//write code here.
}
In your manifest where you have declared your service, add this
android:process="remote"

Android service keeps running indefinitely

I'm trying to create a service in android which i want to keep running in background indefinitely. So I tried to create one like :
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, mssg, Toast.LENGTH_SHORT).show();
}
public int onStartCommand(Intent intent, int flags,int startid) {
Toast.makeText(this, mssg, Toast.LENGTH_LONG).show();
Log.d("Start:", "Service running");
// my code here
return START_STICKY;
}
But when I run this code, the toast messages and logs are only shown once , so does it mean service runs only first time. If it is running again n again which API of it is being called repeatedly ?
Thanks,
shadow.
Running a Service indefinitely and running the same piece of code again and again are two very different things. The piece of code you provided will allow the service to be running the background as long as the Android system doesn't decide to stop it.
Not sure what functionality you are looking to implement, but i suggest you read up on what exactly a Service is used for and what your requirements are.
i suggest you change return START_STICKY;
with return START_NOT_STICKY;
as details given in documentation here.

Categories

Resources