Cagri Yalcin
Cagri Yalcin

Reputation: 402

Using Asynctask when the app is killed

I need to use AsyncTask that called "Logout" when my app is killed by swiped. I used Service to handle this event but it doesn't work.

Added service tag in AndroidManifest.xml

    <service
        android:name=".MyService"
        android:stopWithTask="false" />

My Service code

public class MyService extends Service {

    PostClass post = new PostClass();

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("ClearFromRecentService", "Service Started");
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        new Logout().execute();
        Log.d("ClearFromRecentService", "Service Destroyed");
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Log.e("ClearFromRecentService", "END");
        new Logout().execute();
        stopSelf();
    }

    private class Logout extends AsyncTask<Void, Void, Void> {
        JSONObject j;
        ProgressDialog pDialog;
        JSONObject jso;
        String veri_string = "";

    protected void onPreExecute() {
        Log.e("MyService", "onPreExecute()");
    }

    protected Void doInBackground(Void... unused) {
        Log.e("MyService", "doInBackground()");
        return null;
    }

    protected void onPostExecute(Void unused) {
        Log.e("MyService", "onPostExecute()");
    }
    }
    }

I started this service in my first activity.

    startService(new Intent(this, MyService.class));

is there any way to solve this problem ? Thanks..

Edit: i changed my AsyncTask code. i put some logs after the all lines. When i see my Logcat, "test1", "test2", "test3", "test4" are showing but "test5" and the others are not.

Upvotes: 1

Views: 583

Answers (2)

goodev
goodev

Reputation: 704

EDIT: I test with my phone today, and Use IntentService in other process is working :

    <service
        android:name=".LogoutService"
        android:process=":LogoutProcess"/>
    <!-- LogoutService use a different process, So when MyService is destroyed can
         start LogoutService -->
    <service
        android:name=".MyService"
        android:enabled="true"
        android:exported="false"
        android:stopWithTask="false"/>

And the two services code:

public class MyService extends Service {
    public static final String TAG = "MyService";
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate() called");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Log.e(TAG, "onTaskRemoved() called with: rootIntent = [" + rootIntent + "]");
        Intent logoutService = new Intent(this, LogoutService.class);
        startService(logoutService);
        this.stopSelf();
    }
}

LogoutService.java code

public class LogoutService extends IntentService {
    public static final String TAG = "LogoutService";
    public LogoutService() {
        super(TAG);
        Log.e(TAG, "LogoutService() called");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.e(TAG, "onHandleIntent() called with: intent = [" + intent + "]");
        // This is in the background thread, just call your logout logic:
        try {
            Log.e(TAG, "onHandleIntent: " );
            HttpURLConnection connection = (HttpURLConnection) new URL("https://www.google.com").openConnection();
            String result = readInputStreamToString(connection);
            Log.e(TAG, "onHandleIntent() result = [" + result + "]");
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "onHandleIntent: 111e" );
        }
        Log.e(TAG, "onHandleIntent: 111a" );
    }
}

And the logcat:

03-07 10:04:05.969 8146-8146/org.goodev E/MyService: onCreate() called
03-07 10:04:05.969 8146-8146/org.goodev E/MyService: onStartCommand() called with: intent = [Intent { cmp=org.goodev/com.google.samples.gridtopager.MyService }], flags = [0], startId = [1]
03-07 10:04:10.940 8146-8146/org.goodev E/MyService: onTaskRemoved() called with: rootIntent = [Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=org.goodev/com.google.samples.gridtopager.MainActivity }]
03-07 10:04:10.952 1126-1848/? I/ActivityManager: Start proc 8287:org.goodev:LogoutProcess/u0a248 for service org.goodev/com.google.samples.gridtopager.LogoutService
03-07 10:04:11.016 8287-8287/? E/LogoutService: LogoutService() called
03-07 10:04:11.018 8287-8302/? E/LogoutService: onHandleIntent() called with: intent = [Intent { cmp=org.goodev/com.google.samples.gridtopager.LogoutService }]
03-07 10:04:11.018 8287-8302/? E/LogoutService: onHandleIntent: 
03-07 10:04:12.154 8287-8302/org.goodev:LogoutProcess E/LogoutService: onHandleIntent() result = [<!doctype html><html lang="zh-HK"><head><meta content="width=device-width,minimum-scale=1.0" name="viewport"><meta content="telephone=no" name="format-detection"><meta content="address=no" name="format-detection">...orstr=#3f76d3,GradientType=0)}.gb_8a{display:none!import
03-07 10:04:12.154 8287-8302/org.goodev:LogoutProcess E/LogoutService: onHandleIntent: 111a

WARNING: Because the LogoutService is running in other process. So in your logcat do not select "Show only selected application" filter, you should use no filter and filter by tag "MyService|LogoutService".


Why not use IntentService:

  @Override
  protected void onDestroy() {
    // On your main activity's onDestroy method
    Intent logoutService = new Intent(this, LogoutService.class);
    startService(logoutService);
    super.onDestroy();
  }

and

public class LogoutService extends IntentService {
    public LogoutService() {
        super("LogoutService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        // This is in the background thread, just call your logout logic:
        List<NameValuePair> params = new ArrayList<>();
        try {
            veri_string = post.httpPost(cikisURL, "POST", params, 10000);
            jso = new JSONObject(veri_string);
        }
        catch (JSONException e){
            e.printStackTrace();
        }
        Log.e("Response: ", veri_string);
    }
}

Upvotes: 2

Chetan Kumar Patel
Chetan Kumar Patel

Reputation: 287

public class MyService extends Service {

    PostClass post = new PostClass();

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("ClearFromRecentService", "Service Started");
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        new Logout().execute();
        Log.d("ClearFromRecentService", "Service Destroyed");
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Log.e("ClearFromRecentService", "END");
        new Logout().execute();
        stopSelf();
    }

    private class Logout extends AsyncTask<Void, Void, Void> {
        JSONObject j;
        ProgressDialog pDialog;
        JSONObject jso;
        String veri_string = "";

        protected void onPreExecute() {
        }

        protected Void doInBackground(Void... unused) {
            List<NameValuePair> params = new ArrayList<>();
            try {
                veri_string = post.httpPost(cikisURL, "POST", params, 10000);
                jso = new JSONObject(veri_string);
            }
            catch (JSONException e){
                e.printStackTrace();
            }
            Log.e("Response: ", veri_string);

            return null;
        }

        protected void onPostExecute(Void unused) {
            try {
                if(jso.has("data")) {

                }
                else {

                }
                pDialog.dismiss();
            }
            super.onDestroy();
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    }

Try this

Upvotes: 0

Related Questions