Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid service calling onDestroy before workerthread ends
    text
    copied!<p>I have a service that I'm using to send SOAP Webservice calls. Everything is working perfectly and it never crashes, but I kinda think it should.</p> <p>My problem is that when I have long running queries (10-50 sec.) onDestroy() is called before my workerthread is done (and I call stopSelfResult). Could it be that System.out.println isn't executed right away/out of sync (cached) in the LogCat window?</p> <p>The is how a start the service through QueryBase class:</p> <pre><code>QueryBase someService = new QueryBase(myActivity); someService.execute(...); </code></pre> <p>My QueryBase Class</p> <pre><code>public class QueryBase { private WeakReference&lt;Activity&gt; currentActivity = null; private static class ResponseHandler extends Handler { private QueryBase mQueryBase; public ResponseHandler(QueryBase vQueryBase) { mQueryBase = vQueryBase; }; public void handleMessage(Message message) { Bundle extras = message.getData(); mQueryBase.handleResult(message.arg1,message.arg2,extras.getInt("FRAMEID"),extras.getString("RESPONSE")); mQueryBase=null; }; }; public QueryBase(Activity vActivity) { currentActivity = new WeakReference&lt;Activity&gt;(vActivity); } /*************************************************************************** * Start the service **************************************************************************/ public boolean execute(Activity vActivity, int cmdID, int frameID, String serverAddress, int requestType, String request) { // Valid activity if (vActivity==null) return false; // Test to see if network is connected if (!isOnline(vActivity)) return false; Intent webService = new Intent(vActivity, WebService.class); final ResponseHandler responseHD = new ResponseHandler(this); Messenger messenger = new Messenger(responseHD); webService.putExtra("QUERYRESULT_MESSENGER",messenger); webService.putExtra("CMDID", cmdID); webService.putExtra("FRAMEID",frameID); webService.putExtra("SERVER_ADDRESS",serverAddress); webService.putExtra("REQUEST_TYPE",requestType); webService.putExtra("REQUEST",request); vActivity.startService(webService); return true; } /*************************************************************************** * Is my Android connected? **************************************************************************/ private Boolean isOnline(Activity vActivity) { ConnectivityManager connMgr = (ConnectivityManager) vActivity.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null &amp;&amp; networkInfo.isConnected()) return true; else return false; } /*************************************************************************** * Get current Activity **************************************************************************/ public Activity getCurrentActivity() { Activity ac = currentActivity.get(); if (ac!=null) { if ((ac.isFinishing()) || (ac.activityDestroyed)) { return null; }; } return ac; }; /*************************************************************************** * XML result from webservice **************************************************************************/ public void handleResult(int resultCode, int cmdID, int frameID, String response) { System.out.println("DEFAULT HANDLER: ResultCode: " + resultCode); }; } </code></pre> <p>My WebService Class</p> <pre><code>public class WebService extends Service { public static final int WS_RT_BLOOSOAP = 0; public static final int WS_RT_RSS = 1; public static final int WS_RESULT_OK = 0; public static final int WS_RESULT_UNABLE_TO_CONNECT = 2; public static final int WS_RESULT_INVALID_REQUEST = 3; public static final int WS_RESULT_UNKNOWN_ERROR = 999; static private SparseBooleanArray workList=null; // Only one job with the same frameID is allowed to run @Override public void onCreate() { System.out.println("#### WebService onCreate"); if (workList==null) workList = new SparseBooleanArray(); } @Override public void onDestroy() { System.out.println("#### WebService onDestroy"); } /*************************************************************************** * Start working **************************************************************************/ @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("WebService Start ID=" + startId); final int currentID = startId; final Intent currentIntent = intent; Runnable workerRunnable = new Runnable() { public void run() { System.out.println("WebService Thread Start - ID=" + currentID); int resultCode; Bundle responseExtras = new Bundle(); resultCode = serverRequest(currentIntent,responseExtras); sendResponse(currentIntent,resultCode,responseExtras); System.out.println("WebService Thread End - ID=" + currentID); Bundle extras = currentIntent.getExtras(); if (extras != null) { int frameID = extras.getInt("FRAMEID"); System.out.println("&gt;&gt;&gt;&gt;&gt;&gt;&gt; PUT FALSE " + frameID); workList.put(frameID, false); }; stopSelfResult(currentID); } }; if (intent!=null) { Bundle extras = intent.getExtras(); if (extras != null) { int frameID = extras.getInt("FRAMEID"); Boolean found = workList.get(frameID,false); if (!found) { System.out.println("&gt;&gt;&gt;&gt;&gt;&gt;&gt; PUT TRUE FRAMEID=" + frameID); workList.put(frameID, true); Thread workerThread = new Thread(workerRunnable); workerThread.start(); } else { System.out.println("&gt;&gt;&gt;&gt;&gt;&gt;&gt; Allready running FRAMEID=" + frameID); } }; }; return Service.START_STICKY; }; /*************************************************************************** * No binding **************************************************************************/ @Override public IBinder onBind(Intent intent) { return null; } /*************************************************************************** * Send webservice request and return result in responseExtras **************************************************************************/ private int serverRequest(Intent intent, Bundle responseExtras) { ... }; /*************************************************************************** * Send response back to service caller using Messenger.send() **************************************************************************/ private boolean sendResponse(Intent intent, int resultCode, Bundle responseExtras) { ... }; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload