【问题标题】:Using ResultReceiver in Android在 Android 中使用 ResultReceiver
【发布时间】:2011-05-29 11:59:35
【问题描述】:

基本上,我想从 IntentService 建立对 Activity 的回调。我的问题与此处回答的问题非常相似:

Restful API service

但是,在应答代码中,活动代码被视为实现 ResultReceiver。除非我遗漏了什么,否则 ResultReceiver 实际上是一个类,因此它无法执行此实现。

所以本质上,我在问将 ResultReceiver 连接到该服务的正确方法是什么。在这方面,我对 Handler 和 ResultReceiver 的概念感到困惑。任何工作示例代码将不胜感激。

【问题讨论】:

    标签: android service callback android-activity


    【解决方案1】:
    1. 您需要使自定义结果接收器类扩展自 结果接收器

    2. 然后在你的activity中实现resultreceiver接口

    3. 将自定义resultreceiver对象传递给intentService并在 intentservice 只是获取接收者对象并调用 receiver.send() 函数将任何内容发送到调用活动 捆绑对象。

      这里是 customResultReceiver 类:

       public class MyResultReceiver extends ResultReceiver {
      
          private Receiver mReceiver;
      
          public MyResultReceiver(Handler handler) {
              super(handler);
              // TODO Auto-generated constructor stub
          }
      
          public interface Receiver {
              public void onReceiveResult(int resultCode, Bundle resultData);
      
          }
      
          public void setReceiver(Receiver receiver) {
              mReceiver = receiver;
          }
      
          @Override
          protected void onReceiveResult(int resultCode, Bundle resultData) {
      
              if (mReceiver != null) {
                  mReceiver.onReceiveResult(resultCode, resultData);
              }
          }
      
      }
      

    在你的activity中实现Myresultreceiver.receiver接口,创建一个类变量

    Public MyResultReceiver mReceiver;
    

    在 onCreate 中初始化这个变量:

    mReceiver = new MyResultReceiver(new Handler());
    
    mReceiver.setReceiver(this);
    

    通过以下方式将此 mReceiver 传递给 intentService:

    intent.putExtra("receiverTag", mReceiver);
    

    并像这样在 IntentService 中获取:

    ResultReceiver rec = intent.getParcelableExtra("receiverTag");
    

    并使用 rec 将任何内容发送到活动:

    Bundle b=new Bundle();
    rec.send(0, b);
    

    这将在活动的 onReceiveResult 中接收。完整代码可以查看:IntentService: Providing data back to Activity

    编辑:您应该在 onResume 中调用 setReceiver(this) 并在 onPause() 中调用 setReceiver(null) 以避免泄漏。

    【讨论】:

    • 这对我很有用。谢谢!很好的解释!
    • 那么 ResultReceiver 总是与 IntentService 齐头并进吗?有没有更简单的方法来完成 ResultReceiver 的工作?我的意思是,这个架构看起来太复杂了,有太多的循环依赖。
    • 但是当Activity 被重新创建时,你将永远无法取回你的结果,而且 - 泄露被破坏的Activity
    • This answer 通过利用ResultReceiver 实现Parcelable 的事实来解决屏幕旋转/活动娱乐场景。它可以在onSaveInstanceState(Bundle outState) 期间保存并从Bundle savedInstanceState 重新创建。
    • 如果你将mReceiver作为实例变量保存在Activity中,然后将mReceiver传递给IntentService,那你是不是还有一个IntentService通过mReceiver对Activity的隐式引用?
    【解决方案2】:

    您通过子类化来覆盖方法。它不必是一个接口来做到这一点。

    例如:

    intent.putExtra(StockService.REQUEST_RECEIVER_EXTRA, new ResultReceiver(null) {
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            if (resultCode == StockService.RESULT_ID_QUOTE) {
                ...
            }
        }
    });
    

    【讨论】:

    • 据我所知,这只是答案 - 你能显示相应的 IntentService 端代码,它为 send() 方法解组 ResultReceiver 吗?这给我带来了问题。
    • ... half (sic) ...我回去研究了 Google IO iosched 的示例代码,并意识到我让我的“可拆卸结果接收器”变得太复杂了。事实证明,在服务器端,正如人们所期望的那样,只需使用 intent.getExtra("receiver-key") 即可检索额外内容。没有什么特别的魔法。
    • 非常简单方便。
    • 但是匿名类包含对封闭类的隐式引用。如果这个类是Activity,我们在配置更改期间似乎存在内存泄漏。
    【解决方案3】:

    我创建了一个简单的示例来演示如何使用ResultReceiver

    MainActivity

    public class MainActivity extends AppCompatActivity {
    
        private final static String TAG = MainActivity.class.getSimpleName();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Intent serviceIntent = new Intent(this, MyService.class);
            serviceIntent.putExtra("logName", "MAIN_ACTIVITY");
            serviceIntent.putExtra(MyService.BUNDLED_LISTENER, new ResultReceiver(new Handler()) {
                @Override
                protected void onReceiveResult(int resultCode, Bundle resultData) {
                    super.onReceiveResult(resultCode, resultData);
    
                    if (resultCode == Activity.RESULT_OK) {
                        String val = resultData.getString("value");
                        Log.i(TAG, "++++++++++++RESULT_OK+++++++++++ [" + val + "]");
                    } else {
                        Log.i(TAG, "+++++++++++++RESULT_NOT_OK++++++++++++");
                    }
                }
            });
            startService(serviceIntent);
        }
    }
    

    我的服务

    public class MyService extends Service {
    
        private final static String TAG = MyService.class.getSimpleName();
        public final static String BUNDLED_LISTENER = "listener";
    
        @Override
        public void onCreate() {
            super.onCreate();
    
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            String logName = intent.getStringExtra("logName");
            ResultReceiver receiver = intent.getParcelableExtra(MyService.BUNDLED_LISTENER);
    
            Bundle bundle = new Bundle();
            bundle.putString("value", "30");
            receiver.send(Activity.RESULT_OK, bundle);
            return Service.START_NOT_STICKY;
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
    }
    

    【讨论】:

    • 我在看两年前写的代码,完全忘记了ResultReceivers,谢谢。
    【解决方案4】:

    在android中使用Resulteceiver

    1. 创建 SomeResultReceiver 从 resultReceiver 扩展

    2. 使用 on 方法创建接口 someReceiver,例如 onReceivResult(int resultCode,Bundle resultData);

    3.在 someResultreceiver 中使用 someReceiver

    1. 创建 someService 扩展 IntentService 并使用 someresultReceiver.send() 方法将结果从服务发送到 someOne 类(例如:MyActivity)

    2. 在 Activity 上实现 somereceiver

    6.MyActivity 类中的 someResultReceiver 实例化和 setreceiver

    1. 使用 Intent 和 putExtra someResultreceiver 实例启动服务

    更多详情 ResultReceiver 类见enter link description here

    【讨论】:

    • 链接已失效。请修复它,否则您将获得更多反对票。
    猜你喜欢
    • 1970-01-01
    • 2011-08-10
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    相关资源
    最近更新 更多