android.os.ResultReceiver
together with the service.onHandleIntent(Intent intent)
method in a separate thread from the UI. Simple Service does not allow this because it runs in the main thread. It is necessary to organize the launch of the stream from the Service. public class AppResultsReceiver extends ResultReceiver { public interface Receiver { public void onReceiveResult(int resultCode, Bundle data); } private Receiver mReceiver; public AppResultsReceiver(Handler handler) { super(handler); } public void setReceiver(Receiver receiver) { mReceiver = receiver; } @Override protected void onReceiveResult(int resultCode, Bundle resultData) { if (mReceiver != null) { mReceiver.onReceiveResult(resultCode, resultData); } } }
Receiver
). When the result is onReceiveResult()
in onReceiveResult()
, a check is made for a non-null callback. Further in the activation code, it will be shown how to activate and deactivate the receiver using this callback. public class AppService extends IntentService { public AppService() { this("AppService"); } public AppService(String name) { super(name); } @Override protected void onHandleIntent(Intent intent) { final ResultReceiver receiver = intent.getParcelableExtra(Constants.RECEIVER); receiver.send(Constants.STATUS_RUNNING, Bundle.EMPTY); final Bundle data = new Bundle(); try { Thread.sleep(Constants.SERVICE_DELAY); data.putString(Constants.RECEIVER_DATA, "Sample result data"); } catch (InterruptedException e) { data.putString(Constants.RECEIVER_DATA, "Error"); } receiver.send(Constants.STATUS_FINISHED, data); } }
onHandleIntent()
will be called after the calling code (UI classes, etc.) executes startService()
. The ResultReceiver instance will be retrieved from the intent and the OK command will be sent to it immediately, I went to work. After doing useful work in this method, the results (extracted from JSON classes-models, strings, anything) are placed in a bundle and sent to the receiver. Moreover, different codes are used to indicate the type of response (described by constants). How ResultReceiver receives and sends data can be read in its source code. public class MainActivity extends Activity implements AppResultsReceiver.Receiver { private AppResultsReceiver mReceiver; private ProgressBar mProgress; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mProgress = (ProgressBar) findViewById(R.id.progressBar); } @Override protected void onResume() { super.onResume(); mReceiver = new AppResultsReceiver(new Handler()); mReceiver.setReceiver(this); } @Override protected void onPause() { super.onPause(); mReceiver.setReceiver(null); } public void onStartButtonClick(View anchor) { final Intent intent = new Intent("SOME_COMMAND_ACTION", null, this, AppService.class); intent.putExtra(Constants.RECEIVER, mReceiver); startService(intent); } @Override public void onReceiveResult(int resultCode, Bundle data) { switch (resultCode) { case Constants.STATUS_RUNNING : mProgress.setVisibility(View.VISIBLE); break; case Constants.STATUS_FINISHED : mProgress.setVisibility(View.INVISIBLE); Toast.makeText(this, "Service finished with data: " + data.getString(Constants.RECEIVER_DATA), Toast.LENGTH_SHORT).show(); break; } } }
AppResultsReceiver.Receiver
interface. When starting, it creates an instance of the receiver; when it is paused, it is decoupled from listening to responses from the service. When a button is clicked, a command is formed (intent), a link to our ResultReceiver
is placed in it and the service is started.onReceiveResult()
method checks the response code and takes the appropriate action. That's all.Source: https://habr.com/ru/post/167679/
All Articles