【问题标题】:Debugging IntentService that syncs ParseObjects调试同步 ParseObjects 的 IntentService
【发布时间】:2015-06-13 04:06:14
【问题描述】:

我有一个使用 parse.com 作为其后端的 android 项目。为了减少 api 调用的数量,我一直将“不那么重要”的数据固定到本地数据存储中,并尝试在每个用户会话中同步一次。我为此使用了 IntentService。我正在调用 IntentService,如下所示。但是当调用 IntentService 时,我看不到任何日志消息或调试断点被调用。

问题 1:如何调试任何 Intent 服务?

问题 2:我想在每个用户会话(每次用户打开和关闭应用程序时)执行一次服务。我不想将代码添加到活动的 onPause 方法中,因为我的应用程序有多个活动,因此 onPause 在会话中被多次调用。因此,我从活动的 onBackPressed 调用服务,这是用户退出应用程序之前的最后一个屏幕。这是万无一失的吗?

意图调用代码:

@Override
public void onBackPressed() {
    if(exitCount == 1)
    {
        exitCount=0;

        Intent i= new Intent(this, SyncChoiceService.class);
        this.startService(i);
        super.onBackPressed();
    }
    else
    {
        Toast.makeText(getApplicationContext(), "Press Back again to quit.", Toast.LENGTH_SHORT).show();
        exitCount++;
    }

    return;
}

IntentService 代码

    public class SyncChoiceService extends IntentService {

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public SyncChoiceService(String name) {
        super("SyncChoiceService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        //android.os.Debug.waitForDebugger();
// Adding this waitForDebugger doesn't make a difference
        ParseQuery query = new ParseQuery("PostChoice");
        query.fromPin();
        query.findInBackground(new FindCallback<ParseObject>() {
            @Override
            public void done(final List<ParseObject> list, ParseException e) {
                    if(list!=null)
                    {
                        if(!list.isEmpty())
                        {
                            ParseObject.saveAllInBackground(list, new SaveCallback() {
                                @Override
                                public void done(ParseException e) {
                                    ParseObject.unpinAllInBackground(list, new DeleteCallback() {
                                        @Override
                                        public void done(ParseException e) {
                                            Log.i("Unpinned ","everything");
                                        }
                                    });
                                }
                            });
                        }
                    }
            }
        });

    }
}

【问题讨论】:

  • onHandleIntent的开头添加一些Log.d
  • 您确定这些东西正在进入本地数据存储区吗?您的列表可能为空并且该语句永远不会被记录。您可以尝试在解析调用之外记录一些内容。
  • 我在onHandleIntent的请求中添加了Log.d,也没有打印出来。
  • 对不起,我刚刚看到你已经添加了waitForDebugger
  • 您的服务是否正常启动?尝试在实际启动服务时记录一些内容,然后查看是否曾经调用过 onHandleIntent。此外,这只是一个旁注,您确实在清单中声明了您的服务,对吗?

标签: android android-intent intentservice android-debug


【解决方案1】:

问题 1:如何调试任何 Intent 服务? 如 cmets 中所述,您应该能够设置断点并将调试器附加到服务。

问题2:我想执行服务...? 这将取决于您的要求以及您希望如何定义会话。

如果会话定义为用户登录/注销时,那么您可以简单地将代码简单地放入您的登录/注销逻辑中

如果您将会话定义为当您的应用程序处于前台/直到它进入后台/被终止时,它会变得更加复杂。我会尽量提供尽可能多的信息/案例:

启动应用程序是更容易的部分,因此,您可以简单地在启动器活动的onCreate 中启动您的服务,或者如果您对它进行子类化,甚至可以在ApplicationonCreate 中启动您的服务

关闭应用取决于您定义为closing 的内容。如果您要求用户明确退出应用程序,那么您不需要处理以下情况:

用户只需按下主页按钮即可将应用程序置于后台,在这种情况下onBackPressed 将不会被调用,并且系统可能会在后台清理您的应用程序,因此您将永远没有机会启动你的服务。在这种情况下,系统将调用onSaveInstanceState 并让您有机会启动您的服务。 (如果您不关心这种情况,那么您应该没问题)。这里的一个极端情况是onSavedInstance 状态也会在屏幕旋转时调用,因此您需要一些逻辑来区分应用程序何时进入后台与屏幕旋转

另一件事: onHandleIntent 在后台线程上被调用,所以你可以使用同步版本的find saveunpin 这将帮助你避免所有的嵌套。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多