从onDestroy调用IntentService

6
当用户关闭应用程序时,我希望在服务器端清空与MAC地址相关的表格。因此,我从MainActivity中的onDestroy()方法启动IntentService类,但服务未能启动。我已经在Manifest中注册了它。当我将代码放在onStop()中时,服务就会启动。
由于应用程序必须能够在后台记录数据(纬度、经度、速度、MAC和时间),因此我无法在onPause()或onStop()中完成此任务。
如果无法使用这种方式,我该如何处理?
MainActivity中的onDestroy():
@Override
protected void onDestroy() {
    super.onDestroy();
    WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    WifiInfo wInfo = wifiManager.getConnectionInfo();
    String macAddress = wInfo.getMacAddress();

     JsonObject  jsonObject = new  JsonObject();
     jsonObject.addProperty("mac", macAddress);

    System.out.println("JsonObject" + jsonObject);

    String json = jsonObject.toString();

    Intent intent2 = new Intent(MainActivity.this,
            ClearTable.class);
    intent2.putExtra("json_mac", json);
    startService(intent2);

}

IntentService class:

public class ClearTable extends IntentService{

    public ClearTable() {
        super("IntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        BufferedReader reader = null;

        try {
            String jSONString = intent.getStringExtra("json_mac");
            System.out.println("xyz The output of : doInBackground "
                    + jSONString);
            URL myUrl = new URL(
                    "https://serverside-apple.rhcloud.com/webapi/test");
            HttpURLConnection conn = (HttpURLConnection) myUrl
                    .openConnection();
            conn.setRequestMethod("POST");
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(10000);
            conn.connect();             
            DataOutputStream wr = new DataOutputStream(
                    conn.getOutputStream());
            // write to the output stream from the string
            wr.writeBytes(jSONString);
            wr.close();             
            System.out.println("xyz The output of getResponsecode: "
             + conn.getResponseCode());

        } catch (IOException e) {

            e.printStackTrace();

        } finally {
            if (reader != null) {
                try {
                    reader.close();

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

    }

}

清单文件:

 <service android:name=".ClearTable" />

2
onDestroy() 方法不保证一定会被调用,因此在其中放置重要的代码是危险的。 - Sharp Edge
那么我还可以把它放在我的案例中的哪里? - MrPencil
请问您是否可以采纳我的答案? - Sharp Edge
只是一个想法:您还可以在服务器上定时安排表清理。依靠客户端通知服务器它不再存在似乎是一种糟糕的设计,因为它会创建内存泄漏:任何恶意第三方都可以生成多个客户端来填满您的服务器客户端映射。如果第三方突然终止客户端应用程序,则有许多死对象驻留在您的映射中,这些对象永远不会被移除,因为您计划仅在收到客户端调用通知其不相关时才将它们删除。 - Janus Varmarken
1个回答

4

不要抱太大希望,使用 onDestroy() 是非常不可靠的,因为不能保证会被调用,你应该考虑其它方案:

根据您在问题中提到的:

当用户关闭应用程序时,我想清空服务器端的mac地址表。

那么为什么不覆盖基本 Activity(Launching Activity) 的 onBackPressed() 方法?在那里处理您的逻辑。

编辑

针对 OP 评论中关于在后台关闭应用程序时执行某些操作的问题:

不!没有可靠的方法来检测/检测应用程序何时被强制关闭或系统决定杀死它,以便需要恢复内存。


因为我想在用户在后台关闭应用程序时,在服务器端删除记录。 - MrPencil
2
当用户在后台关闭应用程序时,没有办法处理这种情况。相信我,在这方面浪费了太多时间。 - Sharp Edge
另外,onBackPressed() 的问题在于用户可以关闭应用程序而不必按下返回按钮,或者用户在一个活动中永远不会按下返回按钮,因为上一个活动是闪屏活动,在这种情况下按下它没有意义。 - MrPencil
你的启动活动应该只显示一次,而不是在按下返回键时再次显示。正如我所说,在你的情况下没有可靠的方法。大多数人会在onPause()方法中进行清理,但是如果设备被锁定或屏幕变黑并且应用程序仍在运行,则将调用onPause() - Sharp Edge

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