android - How to stop a thread in a service -


today have problem in android project. use service thread in log location information in period of 10s. however, when change screen orientation (portrait -> landscape), period messed up.

i think may run thread got 1 more thread running behind once rotate screen. have print log messages , seems guessing right.

here code:

public class locationservice extends service {     public location loc;     public locationservice()     {     }      @override     public int onstartcommand(intent intent, int flags, int id)     {         thread thread = new thread(new runnable()         {             @override             public void run()             {                 locationmanager locationmanager = (locationmanager)getsystemservice(context.location_service);                 if ( contextcompat.checkselfpermission(locationservice.this, android.manifest.permission.access_coarse_location ) == packagemanager.permission_granted )                 {                     loc = locationmanager.getlastknownlocation(locationmanager.gps_provider);                     if(loc == null) // fall network if gps not available                     {                         loc = locationmanager.getlastknownlocation(locationmanager.network_provider);                     }                     if(loc != null)                     {                         timer timer = new timer();                         final string time = (new date()).tostring();                         timer.scheduleatfixedrate(new timertask()                         {                             @override                             public void run()                             {                                 log.d(time, "hehe");                                 double currentlat = loc.getlatitude();                                 double currentlng = loc.getlongitude();                                 intent done = new intent();                                 done.setaction("location");                                 done.putextra("currentlat", currentlat);                                 done.putextra("currentlng", currentlng);                                 sendbroadcast(done);                                 //toast.maketext(locationservice.this, string.valueof(currentlat) + string.valueof(currentlng), toast.length_long).show();                             }                         }, 10000, 10000);                     }                 }                 else                 {                     toast.maketext(locationservice.this, "please allow app access location", toast.length_long).show();                 }             }         });         thread.start();          return start_sticky; // stay running     }      @override     public ibinder onbind(intent intent)     { //        // todo: return communication channel service. //        throw new unsupportedoperationexception("not yet implemented");         return null;     }  //    @override //    public void ondestroy() //    { //        log.d("hehe","ondestroy"); //        super.ondestroy(); //    }  } 

here code activity:

public class mainactivity extends appcompatactivity {     private toolbar toolbar;     private fragmentmanager fragmentmanager;     private localfragment localfragment;     private serverfragment serverfragment;     private queryfragment queryfragment;     private fragmenttransaction transaction;     public sqlitehelper dbhelper;      @override     protected void oncreate(bundle savedinstancestate)     {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);          dbhelper = new sqlitehelper(this);          //garb handlers         fragmentmanager = getfragmentmanager();         localfragment = (localfragment) fragmentmanager.findfragmentbyid(r.id.fragment_local);         serverfragment = (serverfragment) fragmentmanager.findfragmentbyid(r.id.fragment_server);         queryfragment = (queryfragment) fragmentmanager.findfragmentbyid(r.id.fragment_query);          // initial visibility         transaction = fragmentmanager.begintransaction();         if(this.getresources().getconfiguration().orientation == configuration.orientation_portrait)         {             // toolbar (must put in checking orientation because landscape layout not have toolbar here)             toolbar = (toolbar) findviewbyid(r.id.toolbar);             toolbar.settitle(r.string.toolbar_title);             setsupportactionbar(toolbar);              transaction.show(localfragment);             transaction.hide(serverfragment);             transaction.hide(queryfragment);             transaction.commit();         }         else // orientation_landscape         {             transaction.hide(queryfragment); // landscape orientation not need query function (?)             transaction.show(localfragment);             transaction.show(serverfragment);             transaction.commit();         }          // register network status receiver         intentfilter intentfilter = new intentfilter();         intentfilter.addaction(connectivitymanager.connectivity_action);         networkstatusreceiver mynetworkreceiver = new networkstatusreceiver();         registerreceiver(mynetworkreceiver, intentfilter);          // start location service         intent intent = new intent(this, locationservice.class);         intent.setaction("location");         startservice(intent);          // register location receiver         intentfilter intentfilterlocation = new intentfilter();         intentfilterlocation.addaction("location");         locationreceiver mylocationreceiver = new locationreceiver();         registerreceiver(mylocationreceiver, intentfilterlocation);        }      @override     public boolean oncreateoptionsmenu(menu menu)     {         menuinflater inflater = getmenuinflater();         inflater.inflate(r.menu.menu_main_activity, menu);         return super.oncreateoptionsmenu(menu);     }      @override     public boolean onoptionsitemselected(menuitem item)     {         transaction = fragmentmanager.begintransaction();         // handle click event         if(item.getitemid() == r.id.action_online)         {             transaction.hide(localfragment);             transaction.hide(queryfragment);             transaction.show(serverfragment);             transaction.commit();         }         else if(item.getitemid() == r.id.action_offline)         {             transaction.hide(serverfragment);             transaction.hide(queryfragment);             transaction.show(localfragment);             transaction.commit();         }         else // query         {             transaction.hide(localfragment);             transaction.hide(serverfragment);             transaction.show(queryfragment);             transaction.commit();         }          return super.onoptionsitemselected(item);     }      // receiver network change action     private class networkstatusreceiver extends broadcastreceiver     {         @override         public void onreceive(context context, intent intent)         {             string action = intent.getaction();             if (action.equals(connectivitymanager.connectivity_action)) // if receive network change event broadcast             {                 toast.maketext(context, "network status changed!", toast.length_long).show();                  // why cannot use thread so? calledfromwrongthreadexception: original thread created view hierarchy can touch views. //                thread thread = new thread(new runnable() //                { //                    @override //                    public void run() //                    {                         int type = 0;                         connectivitymanager connectivitymanager = (connectivitymanager) getsystemservice(context.connectivity_service);                         networkinfo networkinfo = connectivitymanager.getactivenetworkinfo(); // current network type                         if (networkinfo != null && networkinfo.isavailable())                         {                             type = networkinfo.gettype();                             string typename = networkinfo.gettypename(); // (?)                             //serverfragment = (serverfragment)fragmentmanager.findfragmentbyid(r.id.fragment_server);                             if (type == connectivitymanager.type_wifi) // wifi                             {                                 wifimanager wifimanager = (wifimanager) getsystemservice(wifi_service);                                 wifiinfo wifiinfo = wifimanager.getconnectioninfo();                                 log.d("wifiinfo", wifiinfo.tostring());                                 log.d("ssid",wifiinfo.getssid());                                 serverfragment.setnetworkstatustext("wifi: " + wifiinfo.getssid());    // thread issues here. wtf                             } else if (type == connectivitymanager.type_mobile) // cellar                             {                                 serverfragment.setnetworkstatustext("mobile data");                             } else // no network                             {                                 serverfragment.setnetworkstatustext("no network");                             }                         } else // no network                         {                             serverfragment.setnetworkstatustext("no network");                         } //                    } //                }); //                thread.start();             }         }     }      // receiver location per 10s     public class locationreceiver extends broadcastreceiver     {         @override         public void onreceive(context context, intent intent)         {             string action = intent.getaction();             if(action.equals("location"))             {                 double currentlat = intent.getdoubleextra("currentlat", 0.0);                 double currentlng = intent.getdoubleextra("currentlng", 0.0);                 date = new date();                 localfragment.addnewlocation(now, currentlat, currentlng); // add list listview                  // todo: 11/5/16 implement sqlite insert                 dbhelper.addentry(now, currentlat, currentlng);                  toast.maketext(mainactivity.this, "current location: " + string.valueof(currentlat) + ", " + string.valueof(currentlng), toast.length_long).show();             }         }     }      public void setnetworkstatus(string networkstatus)     {         serverfragment.setnetworkstatustext(networkstatus);     } } 

my question are:

  1. it seems ondestroy () method not called when rotate screen?
  2. a new service not created when rotate screen?
  3. how can stop thread created previously? or best way handle problem?

it seems ondestroy() method not called when rotate screen?

no, isn't. changing screen orientation kills activity , creates new one, service still running. screen orientation has no effect on this.

a new service not created when rotate screen?

no. service singleton. android not create new instance of service if there 1 running. however, onstartcommand() called again because activity calls startservice() when created.

how can stop thread created previously? or best way handle problem?

the easiest way deal check in onstartcommand() if thread running. if so, don't need start again. save reference thread in member variable (a field) in service , call isalive() on see if running.

also, in ondestroy() should make sure thread shuts down, otherwise continue run after service dead. should create boolean member variable (field) in thread, check in each loop. in ondestroy() of service, set boolean thread exits.


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -