In my android app i have one service which calls some webservices after a fix interval.
App is running perfectly in foreground and refresh data,but when user exit from app and use some other app then my app force close after many times.
Why this app force close while running in background.
Code that i was using for start service -
msgIntent = new Intent(mContext, MyBackgroundService.class);
startService(msgIntent);
and inside onDestroy() of my main activity i have following code to stop service-
if(msgIntent!=null){
stopService(msgIntent);
}
background service call some async task and each aync task onPostExecute() method execute some insert statement in database.
i am not geting why this force close occure.
Please give your comments.
Thanks in advance.
My Service Code
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
callAsynchronousTask();
return Service.START_NOT_STICKY;
}
#Override
public void onCreate() {
mContext = this;
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
callWebservice();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
timer.schedule(doAsynchronousTask, START_DELAY, DELAY);
}
Actually the problem is here
if(msgIntent!=null){
stopService(msgIntent);
}
in your onDestroy(). Because when you close your application so this above code gets called which is closing your service.
And after closing service again you are trying to insert data by calling service + web service. Hence, there is no service object thats why it gets crashed.
To handle this scenario, you need to comment above code which is in onDestroy() & then check/run it, will solve your problem. & there you need to stop your service by other ways. Go step by step.
you stop the service at onDestroy() method. but services are not depend the activity. So try to neglect the stop service.
(or)
try
{
//stop service code
}
catch(Exception e)
{
}
try this.
Related
I want a best consistent solution to call an api to update current location in every 2 minutes on Nougat and higher version. The process should not be terminated even when the app is killed or closed.
Thanks in advance
Create a services:
public class MyServices extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
startService(new Intent(this,MyServices.class));
Timer t = new Timer();
final Handler handler = new Handler();
// Timer task makes your service will repeat after every 20 Sec.
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
//Do network call here
}
});
}
};
//Starts after 20 sec and will repeat on every 20 sec of time interval.
t.schedule(doAsynchronousTask, 3000,3000); // 20 sec timer
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}
Register the service in menifest
<service android:name=".MyServices" />
Start the service in your activity
Intent intent = new Intent(this, MyServices.class);
startService(intent);
if version > N use this
startForegroundService(intent);
Create a service and update from there.
Service will not stop after closing the application but it will get stopped if the application is force stopped.
And also if your app goes to doze mode your app cannot use Internet or GPS service from the background.
You should check out WorkManager to schedule any kind of work you want your app to do.
I'm trying to learn Android Service, I'm very noob. I'm creating a service which will run even after the app is destroyed but when I terminate the App, the Service gets terminated too. I'm trying to make a NotificationService, below is my code that I just tried working with Service.
Manifest:
<service
android:name="com.test.testworks.MyService"
/>
Starting Service via Button Click:
startService(new Intent(this, MyService.class));
Service class MyService.class:
public class MyService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
/* 1. *//*ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
// This schedule a runnable task every 2 minutes
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
}
}, 0, 10000, TimeUnit.SECONDS);*/
/* 2. *//*final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Toast.makeText(MyService.this, "suiubsibddubsuidv", Toast.LENGTH_LONG).show();
handler.postDelayed(this, 10000); //now is every 2 minutes
}
}, 10000);*/
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
I'm checking on my phone where the other Services are running and when I terminate the App, the Service terminates also.
On some phones, you need to add your app explicitly to the list of apps that are allowed to run in the background. Otherwise, Android will not restart your app if it is killed for whatever reason. There should be a settings page which lists installed apps and allows you to add them to this list. It is called "protected apps" on some devices. Especially devices from Xiaomi, LG, Huawei have this feature, but also other phones.
I use Volley library to connect with server in my app. Now, I have to send request in background every 5 minutes also when app is not running (killed by user). How should I do it? With background services, AlarmManager (Google says that it isn't good choice for network operations) or something else?
Or maybe SyncAdapter will be good for it?
You can use a TimerTask with scheduleAtFixedRate in a service class to achieve this, here is an example of Service class, you can use it
public class ScheduledService extends Service
{
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
sendRequestToServer(); //Your code here
}
}, 0, 5*60*1000);//5 Minutes
}
#Override
public void onDestroy()
{
super.onDestroy();
}
}
You can use sendRequestToServer method to connect with the server.
Here is the manifest declaration of the Service.
<service android:name=".ScheduledService" android:icon="#drawable/icon" android:label="#string/app_name" android:enabled="true"/>
To start the service from MainActivity,
// use this to start and trigger a service
Intent i= new Intent(context, ScheduledService.class);
context.startService(i);
I prefer to use Android Handler because it is executes in UI Thread by default.
import android.os.Handler;
// Create the Handler object (on the main thread by default)
Handler handler = new Handler();
// Define the code block to be executed
private Runnable runnableCode = new Runnable() {
#Override
public void run() {
sendVolleyRequestToServer(); // Volley Request
// Repeat this the same runnable code block again another 2 seconds
handler.postDelayed(runnableCode, 2000);
}
};
// Start the initial runnable task by posting through the handler
handler.post(runnableCode);
I am trying to run a service, whem i stop my app that service still run means it's continuing its task. What is the way to stop service when we stop our app? Plese help me how can i stop this service. One more thing is also there if i use intent in this class to move back to that class from where service is calling i moved back but when i press back button on emulator to go back then it display that service screen also.
I am showing the code of service class
public class SetMovableBG_Inbuilt_SetImage extends Service
{
Timer mytimer;
int interval = 2000;
int interval1 = 4000;
Drawable drawable;
WallpaperManager wpm;
int prev = 0;
int numImage;
private ArrayList<Integer> imgId;
#Override
public void onCreate()
{
super.onCreate();
mytimer = new Timer();
wpm = WallpaperManager.getInstance(this);
}
// here i am geting intent from the class from where i am calling this class.
//everything works fine but service not stops even after stop the app
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
imgId = intent.getIntegerArrayListExtra("ImgId");
numImage = imgId.size();
mytimer.schedule(new TimerTask()
{
#Override
public void run()
{
// TODO Auto-generated method stub
if ( prev >= numImage )
{
prev = 0;
}
try
{
wpm.setResource(imgId.get(prev));
}
catch ( IOException e )
{
e.printStackTrace();
}
prev++;
}
}, interval, interval1);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
}
you can use Service.stopService method to stop the service from other component like activities. You can use Service.stopSelf method to stop the service from the service itself. according to doc
A started service must manage its own lifecycle. That is, the system
does not stop or destroy the service unless it must recover system
memory and the service continues to run after onStartCommand()
returns. So, the service must stop itself by calling stopSelf() or
another component can stop it by calling stopService().
To know more about Services see here
Following Googles examples for using a Service, I created a couple of threads like this. I can't use IntentService, because I'm doing something that involves waiting for callbacks.
However, I don't know how to terminate a Thread started in this manner. As I understand it, Threads automatically terminate when the run() method returns. However, this kind of thread doesn't have a run method. My Threads are leaking--they stay alive after stopSelf().
#Override
public void onCreate() {
HandlerThread thread = new HandlerThread("ServiceStartArguments",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
HandlerThread thread2 = new HandlerThread("CallbackHandling",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread2.start();
mServiceLooper = thread.getLooper();
mCallbackLooper = thread2.getLooper();
mServiceHandler = new MyHandler(mServiceLooper);
mCallbackHandler = new Handler(mCallbackLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
mMainThreadHandler=new Handler();
// If we get killed, after returning from here, restart
return START_STICKY;
}
private final class MyHandler extends Handler {
public MyHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
cycle();
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
protected void cycle() {
...
mCallbackHandler.post(new Runnable(){
public void run(){
goAskForSomeCallbacks();
}
});
try {
Thread.sleep(GIVE_UP_TIME);
} catch (InterruptedException e){
//The callback will interrupt this thread to stop it from waiting
Log.d(TAG,"Got early callback, stop waiting.");
}
Thread.interrupted(); //clear the interrupt
doStuff();
}
Try calling the quit method on the corresponding Loopers.
You can call quit method on your handler threads.
e.g.
thread.quit();
thread2.quit();
You can also use the following recommended approach:
but be careful before using it because it cancels all pending jobs
handler.quitSafely();
Force closing the app does it but otherwise they just keep going on their own.