Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/181.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 ResultReceiver回调以可打包的方式通过捆绑包,它是如何工作的?_Android_Callback_Parcelable - Fatal编程技术网

如果Android ResultReceiver回调以可打包的方式通过捆绑包,它是如何工作的?

如果Android ResultReceiver回调以可打包的方式通过捆绑包,它是如何工作的?,android,callback,parcelable,Android,Callback,Parcelable,我已将我的活动的ResultReceiver传递给我的服务 活动代码示例将ResultReceiver传递给我的服务,以便服务可以回调活动: ResultReceiver receiver = new ResultReceiver(new Handler()) { protected void onReceiveResult(int resultCode, Bundle resultData) { //process results } } Intent ins

我已将我的活动的ResultReceiver传递给我的服务

活动代码示例将ResultReceiver传递给我的服务,以便服务可以回调活动:

ResultReceiver receiver = new ResultReceiver(new Handler()) {
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        //process results
    }
}

Intent instructionServiceIntent = new Intent(context, InstructionService.class);
instructionServiceIntent.putExtra("receiver", receiver);
context.startService(instructionServiceIntent);
说明服务代码示例:

protected void onHandleIntent(Intent intent) {
    Bundle parameters = intent.getExtras();
    ResultReceiver resultReceiver = parameters.getParcelable("receiver");
    resultReceiver.send(METHOD_STATUS_RUNNING, Bundle.EMPTY);
}
现在,当我在服务中调用resultReceiver.send方法时,就会执行活动中相应的onReceiveResult方法


我的问题是,这是如何工作的?据我所知,ResultReceiver是作为包裹从活动传递到服务的,这意味着它是该对象的“副本”,而不是对活动中创建的原始ResultReceiver对象的引用。因此,对服务类中ResultReceiver副本上的send方法的调用如何使其使活动中的原始ResultReceiver对象运行其onReceiveResult方法?

ResultReceiver
实现了
Parcelable
,从而可以按意图传递它

对于startservice,只需加载用于启动服务的意图(就像发送给活动的意图一样),然后在服务流程中加载onStartComand()中的意图数据,就更容易了

如果要将消息来回发送到服务,则应绑定到服务startboundservice,并在服务中向活动返回onBind()中的处理程序

这就是ResultReceiver的魔力所在。它只是一条预先填充了处理程序的消息,因此可以序列化并传回

如果您只是想从动态创建的某个片段类中获取回复,或者实际序列化一个回调,那么您可以传入一条消息,该消息由处理该消息的处理程序填充

下面我创建一个处理程序,然后使用该处理程序创建一条消息。然后我开始一个片段,它做了一些模糊的事情,最后返回消息。因此无效消息只是一个副本,但实际上是一个以捆绑方式传递的回调

这是新代码,所以我不知道它有多稳定

public void get_UserEmail(final MyGooglePlayCallback userEmailCallback) {

    //handle message gets called when the fragment calls msg.sendToTarget()
    //
    class JX implements Handler.Callback {
        @Override
        public boolean handleMessage(Message msg) {
            Bundle b = msg.getData();
            String s = "";
            if (b != null) {
                s = b.getString("email");
            }
            msg.recycle();
            userEmailCallback.onComplete(s);

            return true;
        }
    }
    JX jx = new JX();

    Handler h = new Handler(jx);

    final Message msg = Message.obtain(h);

    MyGooglePlayCallback cb;


    // start the account picker to get the email
    String[] accountTypes = new String[]{"com.google"};
    Intent intentx = AccountPicker.newChooseAccountIntent(null, null,
            accountTypes, false, null, null, null, null);

    MyFragmentActivityForResult2 f = MyFragmentActivityForResult2.newInstance(
            intentx, REQUEST_CODE_PICK_ACCOUNT, msg);

    FragmentTransaction fragmentTransaction = fragManager
            .beginTransaction();
    fragmentTransaction.add(f, "xx" + REQUEST_CODE_PICK_ACCOUNT);
    fragmentTransaction.commit();
}







    public static class MyFragmentActivityForResult2 extends Fragment {

    private Message msg;
    private int requestCode;
    private Intent intent;

    static MyFragmentActivityForResult2 newInstance(Intent intent, int requestCode,
                                                    Message message) {

        MyFragmentActivityForResult2 f = new MyFragmentActivityForResult2();
        Bundle args = new Bundle();
        args.putInt("requestCode", requestCode);
        args.putParcelable("message", message);
        args.putParcelable("intent", intent);
        f.setArguments(args);
        return f;
    }

    MyFragmentActivityForResult2() {
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Bundle b = this.getArguments();
        requestCode = b.getInt("requestCode");
        msg = b.getParcelable("message");
        intent = b.getParcelable("intent");
        startActivityForResult(intent, requestCode);
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode,
                                 Intent data) {

        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == this.requestCode) {
            String mEmail = "";
            if (resultCode == Activity.RESULT_OK) {
                mEmail = data
                        .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
            }
            Bundle b = new Bundle();
            b.putString("email", mEmail);
            msg.setData(b);
            msg.arg1 = requestCode;
            msg.arg2 = resultCode;
            msg.sendToTarget();
        }

        fragManager.beginTransaction().remove(this).commit();
    }
}

看到了吗,请注意,Receiver FieldThank先生,我浏览了ResultReceiver的源代码,试图了解它是如何发挥其魔力的。感谢您为我找到这个ResultReceiver。我一直在尝试制作一个包含回调的动态片段。我想这可能是我一直在寻找的答案。我想它只是传递了我在调试器中查看对象时有时看到的疯狂希腊id。尽管如此,它仍然会发送对象的“副本”。我想知道对一个副本调用方法会如何影响对原始副本的更改。根据原始帖子上的评论,阅读ResultReceiver源代码有助于理解。我认为,由于IDK的魔力,我很高兴知道如何继续我自己的项目。虽然在查看之后,我认为它与用于创建ResultCallback的处理程序有关,因为处理程序对消息进行操作,并且消息有一个replyto字段,魔术只是一条消息被传递回replyto字段,所以它是一个副本,但魔术是一条消息被发送给处理程序。我已经制作了其中一个消息处理程序,用于在活动和服务之间来回通信,replyto字段就是神奇之处。