在销毁一个Activity后调用onStartCommand方法

3
我注意到了一个奇怪的情况。我有一个后台Android服务,它运行得很完美。但是当我从我的“最近应用程序”中杀死进程或应用程序时,我的应用程序会再次调用onStartCommand方法。我不知道哪里出错了。我已经搜索了很多,但没有找到合适的解决方案。请问有人能告诉我我做错了什么吗?谢谢!
活动:
public class OptionSelectionActivity extends Activity implements
    OnClickListener {

Timer time;
Intent serviceIntent;
private Button btn_selectionquiz, btn_alerts, btn_history;
ConnectionManager cm;
boolean isInternetPresent = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
 Log.e("onCreate", "im Running");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_option_selection);

    cm = new ConnectionManager(getApplicationContext());
    isInternetPresent = cm.isConnected();

    serviceIntent = new Intent(getApplicationContext(),MyService.class);
//      serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

//  isMyServiceRunning();
    if(!isMyServiceRunning())
    {
        Toast.makeText(getBaseContext(), "There is no service running, starting service..", Toast.LENGTH_SHORT).show();
        startService(serviceIntent);
    }else
    {
        Toast.makeText(getBaseContext(), "Service is already running", Toast.LENGTH_SHORT).show();          
    }

    XmlView();
    RegisterListenerOnXml();
}

private void XmlView() {
    btn_selectionquiz = (Button) findViewById(R.id.optionselection_btn_selectquiz);
    btn_alerts = (Button) findViewById(R.id.optionselection_btn_alerts);
    btn_history = (Button) findViewById(R.id.optionselection_btn_history);
}

private void RegisterListenerOnXml() {
    btn_selectionquiz.setOnClickListener(this);
    btn_alerts.setOnClickListener(this);
    btn_history.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    Intent i;
    // TODO Auto-generated method stub
    isInternetPresent = cm.isConnected();
    if(isInternetPresent)
    {
    switch (v.getId()) {
    case R.id.optionselection_btn_selectquiz:
        // intent calling
        i = new Intent(this, TeacherSelectionActivity.class);
        startActivity(i);
        break;
    case R.id.optionselection_btn_history:
        // intent calling
        i = new Intent(this, QuizHistoryActivity.class);
        startActivity(i);
        break;

    case R.id.optionselection_btn_alerts:
        // intent calling
        i = new Intent(this, GettingAlerts.class);
        startActivity(i);
        break;
    default:
        break;
    }
}else
{
    AlertDialogManager alert = new AlertDialogManager();
    alert.showAlertDialog(OptionSelectionActivity.this, "Internet Conncetion", "No internet Connection", false);
}
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    if(!isMyServiceRunning())
    {
        Toast.makeText(getBaseContext(), "There is no service running, starting service..",      Toast.LENGTH_SHORT).show();
 //         startService(serviceIntent);
    }else
    {
        Toast.makeText(getBaseContext(), "Service is already running", Toast.LENGTH_SHORT).show();          
    }
}

private boolean isMyServiceRunning() {
    ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        String temp = service.service.getClassName();
        if ("com.smartclasss.alerts.MyService".equals(temp)) {
            return true;
        }
    }
    return false;
}

    @Override
protected void onStop() {
    // TODO Auto-generated method stub
    super.onStop();
    Log.e("onSTOP", "im calling...!!!!");
    if(!isMyServiceRunning())
    {
        Toast.makeText(getBaseContext(), "There is no service running, starting service..", Toast.LENGTH_SHORT).show();
//          startService(serviceIntent);
    }else
    {
        Toast.makeText(getBaseContext(), "Service is already running", Toast.LENGTH_SHORT).show();          
    }
}

@Override
protected void onRestart() {
    // TODO Auto-generated method stub
    super.onRestart();

    Log.e("onRestart", "now im calling after onStop");
}

 }

服务:

 public class MyService extends Service{

private SharedPreferences prefs; 
    private String prefName = "userPrefs";
public static String GETTING_ALERTS_URL = "http://"
        + IPAddress.IP_Address.toString()
        + "//MyServices/Alerts/AlertService.svc/alert";
public static String TAG_NAME = "DoitResult";
public static String TAG_ALERT_TITLE = "alertTitle";
static String Serv_Response = "";
static String Serv_GettingQuiz_Response = "";
boolean flag = false;
boolean isServRun = true;
public Timer time;
ArrayList<Alerts> alertsList;
public static final String INTENT_NOTIFY = "com.blundell.tut.service.INTENT_NOTIFY";
// The system notification manager
private NotificationManager mNM;

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}




@Override
public int onStartCommand(Intent intent, int flags, int startId) {


    Log.e("Attendence", "Service Created");
    // TODO Auto-generated method stub
    time = new Timer();
    time.schedule(new TimerTask() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
            final String currentDate = df.format(Calendar.getInstance().getTime());
//              Toast.makeText(getBaseContext(), "Service Started :"+" "+currentDate, Toast.LENGTH_LONG).show();


            if(flag == false)
            {
                try {
                    savingDateinPref(currentDate);


                    new DoInBackground().execute(currentDate);  
                    flag = true;
                    isServRun = false;
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }

            }
            String val = prefs.getString("TAG_KEY", "defValue");
            if(!currentDate.equals(val))
            {
            flag = false;
            prefs = getSharedPreferences(prefName, MODE_PRIVATE); 
            SharedPreferences.Editor editor = prefs.edit(); 

            editor.remove("TAG_KEY");
             //---saves the values--- 
             editor.commit(); 

            }
        }
    },0,5000);
    return START_STICKY;
}

private class DoInBackground extends AsyncTask<String, Void, Void> {

    String cellphoneDate = "";

    ArrayList<Alerts> alertsList = new ArrayList<Alerts>();
    @Override
    protected Void doInBackground(String... params) {
        // TODO Auto-generated method stub
        cellphoneDate = params[0];
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(GETTING_ALERTS_URL + "/"
                + cellphoneDate);
        HttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpGet);

        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        HttpEntity httpEntity = httpResponse.getEntity();
        try {
            Serv_Response = EntityUtils.toString(httpEntity);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            if (Serv_Response != null) {
                ////////////////////////////new code for getting list ///////////////////
                JSONObject jsonObj1 = new JSONObject(Serv_Response);
                JSONArray alertName = jsonObj1.getJSONArray(TAG_NAME);

                for (int i = 0; i < alertName.length(); i++) {
                    JSONObject c = alertName.getJSONObject(i);
                    String alert_title = c.getString(TAG_ALERT_TITLE);
                    Alerts alertObject = new Alerts();
                    alertObject.setAlertTitle(alert_title);
                    alertsList.add(alertObject);
                    }

            }
            }  catch (JSONException e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return null;
    }
    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
    //  Toast.makeText(getBaseContext(), "From Database :" + Serv_GettingQuiz_Response,     Toast.LENGTH_LONG).show();
        //String array[] = new String[size]; 
        for(int i = 0; i < alertsList.size() ; i++ )
        {
        showNotification(alertsList.get(i).getAlertTitle(), "TAP for More Details", i);
        //  savingDate(Serv_GettingQuiz_Response);
        }
    }

}

private void savingDateinPref(String value){

    prefs = getSharedPreferences(prefName, MODE_PRIVATE); 
    SharedPreferences.Editor editor = prefs.edit(); 

    //---save the values in the EditText view to preferences--- 
     editor.putString("TAG_KEY",value); 
     //---saves the values--- 
     editor.commit(); 
}

}

日志记录:

06-03 12:25:22.844: E/onCreate(29973): im Running
06-03 12:25:23.174: E/Attendence(29973): Service Created
06-03 12:25:30.702: E/onSTOP(29973): im calling...!!!!
06-03 12:25:32.274: E/onCreate(29973): im Running
06-03 12:25:33.655: E/onSTOP(29973): im calling...!!!!
06-03 12:25:34.366: E/onCreate(29973): im Running
06-03 12:25:35.878: E/onSTOP(29973): im calling...!!!!
06-03 12:25:36.869: E/onRestart(29973): now im calling after onStop
06-03 12:25:45.027: E/onSTOP(29973): im calling...!!!!

06-03 12:25:48.221: E/Attendence(30447): 服务已创建

在这个日志中,最后一行显示它再次调用了onStartCommand方法。为什么会这样?即使我的Activity没有运行(我是指服务在oncreate方法或onactivity中启动,但在这里,在销毁应用程序时,控制权直接转移到了onStartCommand)。


1
阅读有关Start_sticky的内容,请访问https://dev59.com/P2Yq5IYBdhLWcg3w-FTQ - Raghunandan
@Raghunandan 谢谢您的回复。我已经阅读了它,但是我不想停止我的服务,也不想在杀死进程时收到通知。在我的情况下,START_NOT_STICKY 是没用的。而 START_STICKY 可以正常工作,但是在我杀死进程时会给我发送一个通知 :( - M A.
请注意:不要让服务长时间运行。 - Raghunandan
那么还有什么其他的方法呢?按照我的逻辑,我希望在日期更改时收到通知,每当日期更改时,我的服务就会与 Web 服务通信并获取数据。 - M A.
当您启动应用程序时,请启动服务,并在活动销毁时停止服务。设计由您决定。 - Raghunandan
@MuneebAmjad:我也遇到了类似的问题。但在我的情况下,这个问题只出现在一些设备上,比如说我在三星Galaxy Grand 2上遇到了错误,但在摩托罗拉Moto E2上没有。你有什么解决方法吗? - Kushal
1个回答

3
您的服务将是START_STICKY,因此android框架会重新启动它- > 这将使您调用onStartCommand() 我将我的服务更改为START_NOT_STICKY,因此android框架不会在没有来自我们应用程序的明确请求的情况下自行重新启动我的服务。
要使您的服务为START_NOT_STICKY,只需从onStartCommand()返回值Service.START_NOT_STICKY 这起作用并解决了我的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接