ResultReceiver.java revision d3c5347b3ec0025ec906e2053eaa9b97287c46a5
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v4.os; 18 19import android.os.Bundle; 20import android.os.Handler; 21import android.os.Parcel; 22import android.os.Parcelable; 23import android.os.RemoteException; 24import android.support.v4.os.IResultReceiver; 25 26/** 27 * Generic interface for receiving a callback result from someone. Use this 28 * by creating a subclass and implement {@link #onReceiveResult}, which you can 29 * then pass to others and send through IPC, and receive results they 30 * supply with {@link #send}. 31 * 32 * <p>Note: the implementation underneath is just a simple wrapper around 33 * a {@link Binder} that is used to perform the communication. This means 34 * semantically you should treat it as such: this class does not impact process 35 * lifecycle management (you must be using some higher-level component to tell 36 * the system that your process needs to continue running), the connection will 37 * break if your process goes away for any reason, etc.</p> 38 * @hide 39 */ 40public class ResultReceiver implements Parcelable { 41 final boolean mLocal; 42 final Handler mHandler; 43 44 IResultReceiver mReceiver; 45 46 class MyRunnable implements Runnable { 47 final int mResultCode; 48 final Bundle mResultData; 49 50 MyRunnable(int resultCode, Bundle resultData) { 51 mResultCode = resultCode; 52 mResultData = resultData; 53 } 54 55 public void run() { 56 onReceiveResult(mResultCode, mResultData); 57 } 58 } 59 60 class MyResultReceiver extends IResultReceiver.Stub { 61 public void send(int resultCode, Bundle resultData) { 62 if (mHandler != null) { 63 mHandler.post(new MyRunnable(resultCode, resultData)); 64 } else { 65 onReceiveResult(resultCode, resultData); 66 } 67 } 68 } 69 70 /** 71 * Create a new ResultReceive to receive results. Your 72 * {@link #onReceiveResult} method will be called from the thread running 73 * <var>handler</var> if given, or from an arbitrary thread if null. 74 */ 75 public ResultReceiver(Handler handler) { 76 mLocal = true; 77 mHandler = handler; 78 } 79 80 /** 81 * Deliver a result to this receiver. Will call {@link #onReceiveResult}, 82 * always asynchronously if the receiver has supplied a Handler in which 83 * to dispatch the result. 84 * @param resultCode Arbitrary result code to deliver, as defined by you. 85 * @param resultData Any additional data provided by you. 86 */ 87 public void send(int resultCode, Bundle resultData) { 88 if (mLocal) { 89 if (mHandler != null) { 90 mHandler.post(new MyRunnable(resultCode, resultData)); 91 } else { 92 onReceiveResult(resultCode, resultData); 93 } 94 return; 95 } 96 97 if (mReceiver != null) { 98 try { 99 mReceiver.send(resultCode, resultData); 100 } catch (RemoteException e) { 101 } 102 } 103 } 104 105 /** 106 * Override to receive results delivered to this object. 107 * 108 * @param resultCode Arbitrary result code delivered by the sender, as 109 * defined by the sender. 110 * @param resultData Any additional data provided by the sender. 111 */ 112 protected void onReceiveResult(int resultCode, Bundle resultData) { 113 } 114 115 public int describeContents() { 116 return 0; 117 } 118 119 public void writeToParcel(Parcel out, int flags) { 120 synchronized (this) { 121 if (mReceiver == null) { 122 mReceiver = new MyResultReceiver(); 123 } 124 out.writeStrongBinder(mReceiver.asBinder()); 125 } 126 } 127 128 ResultReceiver(Parcel in) { 129 mLocal = false; 130 mHandler = null; 131 mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder()); 132 } 133 134 public static final Creator<ResultReceiver> CREATOR 135 = new Creator<ResultReceiver>() { 136 public ResultReceiver createFromParcel(Parcel in) { 137 return new ResultReceiver(in); 138 } 139 public ResultReceiver[] newArray(int size) { 140 return new ResultReceiver[size]; 141 } 142 }; 143} 144