Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android startActivityForResult的模拟服务_Android - Fatal编程技术网

Android startActivityForResult的模拟服务

Android startActivityForResult的模拟服务,android,Android,尽管如此,我有不同的情况: 我的应用程序主要由后台服务组成。我想开始外部活动并获得结果 我看到几个选择: 创建虚拟活动并保留对其的引用,以便使用其startActivityForResult。正如我们所知,这会消耗大量内存 使用广播意图代替Android的结果基础设施:要求客户端活动在结束前广播其结果。这种方式打破了这种想法,而且性能效率不高 直接使用检测尝试将startActivityForResult中的代码复制到我的服务中 使用服务接口-序列化并将AIDL连接添加到启动活动的意图。在这种情

尽管如此,我有不同的情况: 我的应用程序主要由后台
服务
组成。我想开始外部活动并获得结果

我看到几个选择:

  • 创建虚拟
    活动
    并保留对其的引用,以便使用其
    startActivityForResult
    。正如我们所知,这会消耗大量内存

  • 使用
    广播意图
    代替Android的结果基础设施:要求客户端活动在结束前广播其结果。这种方式打破了这种想法,而且性能效率不高

  • 直接使用
    检测
    尝试将startActivityForResult中的代码复制到我的服务中

  • 使用服务接口-序列化并将
    AIDL
    连接添加到启动活动的意图。在这种情况下,活动不应该提供结果

  • 第三种方法对我来说更接近于Android,但我不确定是否可以这样做——服务没有它的插装,默认实现似乎总是返回null


    也许你还有其他想法吗?

    我认为选项2是android上最惯用的方式。从
    活动中使用
    startActivityForResult
    是一个同步/阻塞调用,即父活动等待并且在子活动完成之前不执行任何操作。当从
    服务
    工作并与活动交互时,您主要执行异步/非阻塞调用,即服务调用一些要完成的工作,然后等待信号通知它可以继续


    如果您正在使用,则可以让您的活动获取
    服务的引用
    ,然后在其执行工作后调用特定函数。尝试您的选项3将与框架为您提供的内容背道而驰

    我最近在实施三条腿授权流程时一直在考虑这一点。将结果发送回服务进行处理比在“活动”中处理效果更好。它还提供了更好的关注点分离

    虽然没有明确的文档记录,但Android提供了一种简单的方式,可以在任何地方(包括服务)发送和接收结果

    我发现它比传递活动要干净得多,因为这总是伴随着泄露这些活动的风险。此外,调用具体方法的灵活性较低

    要在服务中使用
    ResultReceiver
    ,您需要对其进行子类化,并提供一种处理收到的结果的方法,通常在内部类中:

    public class SomeService extends Service {
    
        /**
         * Code for a successful result, mirrors {@link Activity.RESULT_OK}.
         */
        public static final int RESULT_OK = -1;
    
        /**
         * Key used in the intent extras for the result receiver.
         */
        public static final String KEY_RECEIVER = "KEY_RECEIVER";
    
        /**
         * Key used in the result bundle for the message.
         */
        public static final String KEY_MESSAGE = "KEY_MESSAGE";
    
        // ...
    
        /**
         * Used by an activity to send a result back to our service.
         */
        class MessageReceiver extends ResultReceiver {
    
            public MessageReceiver() {
                // Pass in a handler or null if you don't care about the thread
                // on which your code is executed.
                super(null);
            }
    
            /**
             * Called when there's a result available.
             */
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                // Define and handle your own result codes
                if (resultCode != RESULT_OK) {
                    return;
                }
    
                // Let's assume that a successful result includes a message.
                String message = resultData.getString(KEY_MESSAGE);
    
                // Now you can do something with it.
            }
    
        }
    
    }
    
    在服务中启动活动时,创建结果接收器并将其打包到intent extras中:

    /**
     * Starts an activity for retrieving a message.
     */
    private void startMessageActivity() {
        Intent intent = new Intent(this, MessageActivity.class);
    
        // Pack the parcelable receiver into the intent extras so the
        // activity can access it.
        intent.putExtra(KEY_RECEIVER, new MessageReceiver());
    
        startActivity(intent);
    }
    
    最后,在活动中,打开接收器的包装,并使用
    ResultReceiver#send(int,Bundle)
    将结果发回

    您可以随时发送结果,但我选择在完成之前发送:

    public class MessageActivity extends Activity {
    
        // ...
    
        @Override
        public void finish() {
            // Unpack the receiver.
            ResultReceiver receiver =
                    getIntent().getParcelableExtra(SomeService.KEY_RECEIVER);
    
            Bundle resultData = new Bundle();
    
            resultData.putString(SomeService.KEY_MESSAGE, "Hello world!");
    
            receiver.send(SomeService.RESULT_OK, resultData);
    
            super.finish();
        }
    
    }
    

    谢谢你的想法!现在我在2(更容易实现)和4(更安全/更私密,应该更快)之间进行选择。我真的不同意startActivityForResult是阻塞的(因为它使用回调函数,而不是结果值),而且插装在公共API=)中,谢谢!我的意思是它不是传统意义上的阻塞(例如,阻塞io调用)。它是以您使用它的概念性方式阻塞的。@Qberticus您提供的链接只是指向通用示例页面的链接。它可以通过使用SharedReferences进行简单的破解来实现,谢谢您的解决方案!有一件事:根据Activity.javaGood point,RESULT_OK应该是-1。我认为在这种情况下,可以使用任何值,但最好与平台提供的内容保持一致。我已经更新了答案。您也可以直接使用Activity.RESULT\u OK。您需要在类
    MessageReceiver
    之前添加
    @suppressint(“ParcelCreator”)
    ,否则它会要求您将创建者设置为可包裹。谢谢你的回答。