Contacts

Communication between ACTIVITY and SERVICE. Switch between application screens Data transmission between activati

Somehow I had a task to transfer data from the service to activat. The search for solutions in the standard SDK began, but since there was no time, then flew a bad solution as a database use. But the question was opened and after some time I figured out with a more correct way, which is in SDK - using the Classes of Message, Handler, Messenger.

Idea

We need to transmit data from activat to service and back. How do we do it? To solve our task, we already have everything you need. All you need is to bind service to ATITIVITY using Bindservice, transfer the desired parameters and a bit of magic in the form of using Message classes. And magic is to use the MESSAGE instance variables and in particular replyto. This variable is needed to us so that we can refer to the Messanger service instance from activati \u200b\u200band in the service to the MESSANGER-A copy. In fact, not so simple. At least for my not the most gifted mind. In part, I just improve the documentation that already is - Services also, there is good example on stackoverflow. In any case, I hope the article will be helpful at least someone and I did not dare not in vain.

Example

As an example, we are implementing a service that will increase and reduce the value of the counter and return the result in activati \u200b\u200bin TextView. The layout code is omitted, for there are two buttons and a text field - everything is simple.

Sales

I will give a fully activat code:

Public class MainActivity extends Activity (public static final String TAG \u003d "TestService"; TestServiceConnection testServConn; TextView testTxt; final Messenger messenger \u003d new Messenger (new IncomingHandler ()); Messenger toServiceMessenger; @Override public void onCreate (Bundle savedInstanceState) (super. ONCREATE (SAVEDINSTANCESTATE); setContentView; TestTxtXT \u003d (textView) FindViewByid (R.ID.Test_TXT); Bindservice (New Intent), (TestServconn \u003d New TestServiceConnection ()), Context .Bind_auto_create);) @Override public void onestroy () (super.ondestroy (); unbindservice (TestServconn);) Public Void CountinCrClick (View Button) (NULL, TestService.count_Plus); msg.replyto \u003d Messenger; Try (ToserviceMessenger.send (MSG);) Catch (E.PrintStackTrace ();)) Public Void CountdeCrClick (View Button) (NULL, TestService.count_minus); MSG .replyto. \u003d messenger; Try (ToserviceMessenger.send (MSG);) Catch (E.PrintStackTrace ();)) Private Class Incominghandler Extends Handler (@Override Public Void Handlemessage (MSG.What) (CASE TestService. Get_Count: log.d (Tag, "(Activity) ... Get Count"); testtxt.settext ("" + msg.arg1); break;))) Private Class TestServiceConnection Implements ServiceConnection (@Override Public Void OnserviceConnected (Componentname Name, Ibinder Service) (ToserviceMessenger \u003d New Messenger; // Send the initial value of the Message MSG \u003d Message.Obtain counter (NULL, TestService.Set_Count); MSG.ReplyTo \u003d Messenger; msg.arg1 \u003d 0; // Our counter Try (ToserviceMessenger.send (MSG);) Catch (RemoteException E) (E.PrintStackTrace ();)) @Override public void onservicedisconnected (Componentname Name)))

I will explain. When creating activat, we are immediately tied to the service, implementing the ServiceConnection interface and send a message to the "Set the counter value" service, passing zero and creating a ToserviceMessanger, passing the iBinder interface to the designer. By the way, in the service it is necessary to return this ehemple, otherwise there will be NPE. With this class, we send the message to the service. And here it is magic - we save our other Messenger instance to the replyto variable - the one that receives a response from the server and it is through it that will communicate with activat.

To receive a message from the service, use your handler and just looking for variables we need and make action on them. By clicks on the buttons (CountinCrCrClick, CountdeCrClick methods), send requests to the service, specifying the desired action in the MSG.What variable.

Package com.example.servicetest; Import Android.app.Service; Import android.content. *; Import Android.os. *; Import android.os.Process; Import android.util.log; public class TestService extends Service (public static final int COUNT_PLUS \u003d 1; public static final int COUNT_MINUS \u003d 2; public static final int SET_COUNT \u003d 0; public static final int GET_COUNT \u003d 3; int count \u003d 0; IncomingHandler inHandler; Messenger messanger; Messenger toActivityMessenger; @Override public void onCreate () (super.onCreate (); HandlerThread thread \u003d new HandlerThread ( "ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start (); inHandler \u003d new IncomingHandler (thread.getLooper ()); messanger \u003d New Messenger (InHandler);) @Override Public iBinder Onbind (Return Messanger.getBinder ();) @Override Public Intent OnStartCommand (Return Start_Sticky;) // Message handler Activities Private Class Incominghandler Extends Handler (Super Looper) (Looper Looper) (Looper Looper) @Override Public Void Handlemessage (Message MSG) (//super.handlemessage(msg); toactivityMess enger \u003d msg.replyto; Switch (MSG.What \u003d MSG.ARG1; log.d (mainactivity.tag, "(Service) ... Set Count"); Break; Case Count_Plus: Count ++; log.d (MainActivity.tag , "(Service) ... Count Plus"); break; Case Count_minus: log.d (mainactivity.tag, "(service) ... count minus"); count--; break;) // Send a meter value In activativity Message Outmsg \u003d Message.Obtain (INHANDER, GET_COUNT); outmsg.arg1 \u003d count; outmsg.replyto \u003d Messanger; Try (if (toactivityMessenger! \u003d NULL) toactivityMessenger.send (Outmsg);) Catch (E.PrintStackTrace ();))))

All by analogy with logic in activiti. I do not even know if you need to explain something. The only moment is that I immediately send a request back to activat in Handlemessage, using the magic variable replyto and pulling the above Messenger above. And the second moment I already said is:

@Override Public iBinder Onbind (Intent Arg0) (Return Messanger.GetBinder ();)

without which everything falls. It is this interface instance that will be transmitted to ServiceConnection.

Conclusion

In general, everything. Such a contrived example of interaction of activat and service. It seems to me that the non-trivial interaction is pretty, although someone may seem otherwise.

Questions, clarifications and other in PM. There may be inaccuracies about any aspects, so feel free to write and straighten.
I hope the post was useful to readers.

Last updated: 04/03/2018

To transfer data between two ACTIVITY, an Intent object is used. Through its Putextra () method, you can add the key and the associated value.

For example, transmitting from the current Activity in the Secondactivity "Hello World" strings with the key "Hello":

// Creating an INTENT object to launch Secondactivity Intens Intens \u003d New Intent (this, secondactivity.class); // Transfer of an object with the "Hello" key and the "Hello World" value of Intent.Putextra ("Hello", "Hello World"); // Starting Secondactivity Startactivity (Intent);

The Putextra () method is used to transmit data, which as a value allows you to transfer the simplest types of type data - String, Int, Float, Double, Long, Short, Byte, Char, the arrays of these types, or the Serializable interface object.

To get the sent data when loading Secondactivity, you can use gET.(), in which the object is transmitted:

Bundle arguments \u003d getintent (). GetExtras (); String Name \u003d Arguments.get ("Hello"). Tostring (); // Hello WORLD.

Depending on the type of data sent, when received, we can use a number of Bundle object methods. All of them accept the object key as a parameter. The main ones are:

    get (): universal methodwhich returns the value of the Object type. Accordingly, the receipt field must be converted to the desired type

    getString (): Returns the object type String

    getint (): Returns the value of type int

    getByte (): Returns the value of the BYTE type

    getchar (): Returns the value of type char

    getShort (): Returns a value of type short

    getlong (): Returns a Long value

    getfloat (): Returns the value of type Float

    getDouble (): Returns a Double value

    getBoolean (): Returns a value of type boolean

    getchararray (): Returns an array of CHAR objects

    getintarray (): Returns an array of int objects

    getfloatarray (): Returns an array of Float objects

    getSerializable (): Returns the Serializable interface object

Let us in the project will be defined two ACTIVITY: MainActivity and Secondactivity.

In the Secondactivity code we will determine the data obtaining:

Package com.example.eugene.serializeApp; Import android.Support.v7.app.appCompatactivity; Import android.os.Bundle; Import android.widget.textView; public class SecondActivity extends AppCompatActivity (@Override protected void onCreate (Bundle savedInstanceState) (super.onCreate (savedInstanceState); TextView textView \u003d new TextView (this); textView.setTextSize (20); textView.setPadding (16, 16, 16, 16 ); Bundle arguments \u003d getIntent (). GetExtras (); if (arguments! \u003d NULL) (String Name \u003d Argments.get). Tostring (); String Company \u003d Arguments.getString ("Company"); int Price \u003d arguments.getint ("Price"); textView.setText ("Name:" + Name + "\\ Ncompany:" + Company + "\\ Nprice:" + Price);) SetContentView (textView);))

In this case, in the Secondactivity we get all the data from the Bundle object and display them in the TextView text box. It is assumed that this ACTIVITY will be transmitted three elements - two rows with Name and Company keys and a key with a key Price.

Now we will define the transfer to the Secondactivity of the data. For example, we define the next interface for the MainActivity in the Activity_Main.xml file:

Did you like the article? Share it