草庐IT

android - 如果 Android ResultReceiver 回调作为 Parcelable 通过 Bundle 传递,它如何工作?

coder 2023-12-04 原文

我已将 ResultReceiver 从我的 Activity 传递到我的服务。

Activity 代码示例 将 ResultReceiver 传递到我的服务,以便服务可以对 Activity 进行回调:

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);

InstructionService 代码示例:

protected void onHandleIntent(Intent intent) {
    Bundle parameters = intent.getExtras();
    ResultReceiver resultReceiver = parameters.getParcelable("receiver");
    resultReceiver.send(METHOD_STATUS_RUNNING, Bundle.EMPTY);
}

现在,这工作正常,因为当我在服务中调用 resultReceiver.send 方法时,将执行 Activity 中相应的 onReceiveResult 方法。

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

最佳答案

ResultReciver 实现了 Parcelable,因此它可以在 Intent 中传递。

对于 startservice 来说,加载用于启动服务的 Intent 更容易,就像发送到 Activity 的 Intent 一样,然后在服务进程中将 Intent 数据加载到 onStartComand() 中;

如果您想将消息发送回服务,您应该绑定(bind)到服务 startboundservice 并在服务中将 onBind() 中的处理程序返回给 Activity 。

这就是 ResultReceiver 神奇的地方。它只是一条消息,已预先填充处理程序,因此可以对其进行序列化并传回。

如果您只是想从您即时创建的某个 fragment 类中获得回复,或者一些不符合规范的东西实际上序列化了一个回调,您可以传入一条消息,该消息填充了将处理该消息的处理程序。

下面我创建了一个处理程序,然后使用该处理程序创建了一条消息。然后我开始一个 fragment ,它做了一些模糊的事情并最终返回了消息。所以实际上消息只是一个副本,但它实际上是一个在包中传递的回调。

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

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();
    }
}

关于android - 如果 Android ResultReceiver 回调作为 Parcelable 通过 Bundle 传递,它如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23822692/

有关android - 如果 Android ResultReceiver 回调作为 Parcelable 通过 Bundle 传递,它如何工作?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐