tcp - Android kills the service very frequently -
we prepared android application service maintains mqtt connection our server. service returns *start_sticky* onstartcommand in order android restart service in case kills service resource shortages. problem is, service killed android os. kills service once in few seconds, if no other process works on device(with 2gb of ram). why android killing service frequently? how can lessen number of restarts? service should killed less possible, because disconnects tcp connection , client have reconnect again, causing quite big load on our server. can wrong code? thanks
public class gtandroidmqttservice extends service implements mqttcallback { private void init() { this.clientid = settings.system.getstring(getcontentresolver(), secure.android_id); } @override @deprecated public void onstart(intent intent, int startid) { logger("onstart() called"); super.onstart(intent, startid); } @override public int onstartcommand(intent intent, int flags, int startid) { logger("onstartcommand() called"); if (client == null) { try { init(); conopt = new mqttconnectoptions(); conopt.setcleansession(false); conopt.setusername("..."); conopt.setpassword("..."); try { char[] keystorepass = getstring(r.string.keystorepass).tochararray(); keystore keystore = keystore.getinstance("bks"); keystore.load(getapplicationcontext().getresources().openrawresource(r.raw.prdkey), keystorepass); trustmanagerfactory trustmanagerfactory = trustmanagerfactory .getinstance(keymanagerfactory.getdefaultalgorithm()); trustmanagerfactory.init(keystore); keymanagerfactory kmf = keymanagerfactory.getinstance(keymanagerfactory .getdefaultalgorithm()); kmf.init(keystore, keystorepass); sslcontext sslcontext = sslcontext.getinstance("tls"); sslcontext.init(kmf.getkeymanagers(), trustmanagerfactory.gettrustmanagers(), null); conopt.setsocketfactory(sslcontext.getsocketfactory()); } catch (exception ea) { } client = new mqttclient(this.mqtturl, clientid, new mqttdefaultfilepersistence(folder)); client.setcallback(this); conopt.setkeepaliveinterval(this.keepaliveseconds); } catch (mqttexception e) { e.printstacktrace(); } catch (nosuchalgorithmexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (unsupportedencodingexception e) { // todo auto-generated catch block e.printstacktrace(); } } if (intent == null) { log.i("tag", "android restarted service[start_sticky]"); if (client != null) { trytoestablishconnection(); } } return start_sticky; } public void unsubscribe(string topicname) throws mqttexception { try { client.unsubscribe(topicname); } catch (exception e) { log.i("tag", "unsubscribing topic \"" + topicname + "has failed: " + e.tostring()); } } private void retry() { try { notifyuserwithservicestatus("status changed", "status", "connecting"); client.connect(conopt); notifyuserwithservicestatus("status changed", "status", "user connected #" + (++retrycnt)); } catch (exception e) { notifyuserwithservicestatus("status changed", "status", "cannot connect"); e.printstacktrace(); } } public void subscribe(string topicname, int qos) throws mqttexception { try { client.subscribe(topicname, qos); } catch (exception e) { } } public void disconnect() { try { client.disconnect(); } catch (mqttexception e) { e.printstacktrace(); } } @override public ibinder onbind(intent intent) { logger("onbind() called"); return null; } @override public void oncreate() { logger("oncreate() called"); super.oncreate(); } @override public void connectionlost(throwable arg0) { // connection lost notifyuserwithservicestatus("status changed", "status", "connection lost!"); trytoestablishconnection(); } private void trytoestablishconnection() { if (!retrying) { retrying = true; new thread(new runnable() { @override public void run() { (;;) { try { if (isonline() && !isconnected()) { retry(); thread.sleep(retry_interval); } else if (isconnected()) { retrying = false; break; } else if (!isonline()) { retrying = false; break; } } catch (exception e) { e.printstacktrace(); } } } }).start(); } } private class networkconnectionintentreceiver extends broadcastreceiver { @override public void onreceive(context ctx, intent intent) { powermanager pm = (powermanager) getsystemservice(power_service); wakelock wl = pm.newwakelock(powermanager.partial_wake_lock, "mqtt"); wl.acquire(); if (isonline() && !isconnected()) notifyuserwithservicestatus("status changed", "status", "online not connected"); else if (!isonline()) notifyuserwithservicestatus("status changed", "status", "connection lost!"); trytoestablishconnection(); wl.release(); } } private boolean isconnected() { try { return client.isconnected(); } catch (exception e) { return false; } } private boolean isonline() { connectivitymanager conmgr = (connectivitymanager) getsystemservice(context.connectivity_service); networkinfo = conmgr.getactivenetworkinfo(); if (i == null) return false; if (!i.isconnected()) return false; if (!i.isavailable()) return false; return true; } @override public void ondestroy() { logger("ondestroy() called"); try { client.disconnect(); log.i("tag", "service stopped"); } catch (mqttexception e) { e.printstacktrace(); } super.ondestroy(); } @override public void deliverycomplete(imqttdeliverytoken arg0) { // todo auto-generated method stub } }
it sounds though service running in application process; directly tied activity?
you'll want run different process entirely; can adding following declaration in manifest:
<service android:name=".serviceclassname" android:process=":yourappname_background" >
and use same android:process attribute receiver declarations well.
Comments
Post a Comment