I have a Service running in my app..
This Service has an object for sending message to the server and a function to get that object and use it.
The object is initialized from the Service and yet when the UI gets this objects and use it - it looks like it uses it on the UI Thread..
Is this correct ? Is there a way i can make my object always run from the Service Thread ?
public class ServerMessagesManager extends Service {
private ServerMessagesReceiver serverMessageReceiver;
#Override
public void onCreate() {
super.onCreate();
this.serverMessageReceiver = new ServerMessagesReceiver(app);
}
public ServerMessagesReceiver getServerMessagesReceiver()
{
return serverMessageReceiver;
}
}
Use IntentService instead of Service. If you do network calls in a Service, the UI will stuck. Therefore, use an IntentService since it uses a separate Thread.
And you do not know when a server message will retrieve the data. A NullPointerException could be thrown if objects are accessed as long as network calls are still in progress. Use BroadcastReceivers to fire an Intent whenever a server responds.
As far I know, Android service run on UI thread. If you want to make an asynchronous job, you should use Intent Service
See:
What is the difference between an IntentService and a Service?
Here is an Intent service example you can try.
Related
I know how to save states and restore them, but I just get confused when I have to do work with the Web services and to update UI. For times I was using the AsyncTask but then I came to point where I loose my activity/fragment context for example when I rotate the device. So in this way, I am thinking how other apps are handling such situations.
If I use the IntentService and call my web service from there, then I came to think that for each web service I have to make IntentService differently, and update the UI of each activity and fragment I have to make the BroadcastReceiver for each activity and fragments.
So what is a good practice for calling web service from the activity and the fragments?
How can I Update UI when the service return arrives (or call next service based on first services results)?
If you want your data to be instantly available through configuration changes (which you do), then you probably want to use Loaders.
It gives the developer a mechanism of loading data asynchronously for an activity or fragment. Since loaders are specifically designed to solve the issue of async loading, one does not have to spend too much time designing async tasks to handle all different scenarios efficiently.
Good article about Loaders https://medium.com/google-developers/making-loading-data-on-android-lifecycle-aware-897e12760832
Try using retrofit. It's a great networking libraries for Android apps and it's easy to use.
The entire network call + JSON/XML parsing is completely handled by it (with help from Gson for JSON parsing). Documentation is great and the community is huge.
check out this sample.
I noticed a comment you made:
...and my webservices are soap and I cant change them
The way I'm currently calling my web service, which is also SOAP, is via an Intent. I do this by passing in the data that I'm submitting to the Web service with putExtra then receiving it on my WebService, as you probably do right now. I then get the result from that web call and process it inside an AsyncTask, the async task will then utilize EventBus to post to Results as needed which are received on my MainThread via ThreadMode.Main.
So with that said, I highly recommend the use of a library called EventBus from Greenrobot.
You greatly simplify communication between Activities and Fragments, You can get started immediately using a default EventBus instance available from anywhere in your code. For example, you can do the following.
EventBus.getDefault().post(new ModelForOtherActivityToSee(data));
In the model, you can include anything you want, and react accordingly when received.
The best part is that when received, EventBus handles how the data will be executed by either running ASYNC, MAIN, BACKGROUND
ASYNC - Event handler methods are called in a separate thread. This is always independent from the posting thread and the main thread. Posting events never wait for event handler methods using this mode. Event handler methods should use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number of long-running asynchronous handler methods at the same time to limit the number of concurrent threads. EventBus uses a thread pool to efficiently reuse threads from completed asynchronous event handler notifications.
Background - Subscribers will be called in a background thread. If posting thread is not the main thread, event handler methods will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single background thread that will deliver all its events sequentially. Event handlers using this mode should try to return quickly to avoid blocking the background thread.
MAIN -Subscribers will be called in Android’s main thread (sometimes referred to as UI thread). If the posting thread is the main thread, event handler methods will be called directly (synchronously like described for ThreadMode.POSTING). Event handlers using this mode must return quickly to avoid blocking the main thread.
An example of receiving an event broadcasted from EventBus:
//ThreadMode can be ASYNC, MAIN, BACKGROUND
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(ModelForOtherActivityToSee eventModel) {
/* Do something with eventModel received, this runs on UI thread */
};
Full example on how to use EventBus:
1 - Open your build.gradle for the app and set your dependency for EventBus:
dependencies { compile 'org.greenrobot:eventbus:3.0.0'}
2 - Create your first model to use in publishing an EventBus, I will use a very simplistic example of a model:
package com.myapp.models.eventbusmodels;
public final class EventBusMyModel {
private final String dataRaw
public EventBusMyModel(final String rawData) {
this.dataRaw = rawData;
}
public String getRawData() {
return this.dataRaw;
}
}
3 - Now all that's left is pushing out a broadcast by using from anywhere.
EventBus.post(new EventBusModel("My Data here"));
4 - To enable Activities/Fragments to receive events from EventBus you must attach and detach, this is what I mean. From inside an Activity on the onResume() and onStop() overrides:
public class SomeActivity {
#Override
protected void onResume() {
if(!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
}
#Override
protected void onStop() {
if(EventBus.getDefault().isRegistered(this))
EventBus.getDefault().unregister(this);
super.onStop();
}
}
5 - The final thing to do is receive that broadcast, you can receive it in Any Fragment, Activity, or in all your fragments/activities. Here's an example from inside the SomeActivity:
#Subscribe(threadMode = ThreadMode.MAIN)
public void eventThisNameDoesNotMatter(final EventBusMyModel resultModel) {
String receivedData = resultModel.getRawData();
//Do whatever with receivedData. Since we are on ThreadMode.MAIN, this is on the UI thread.
}
I have implemented a simple Android Service that, by default, is deployed within the same process as my app / apk. I want the Service running concurrently with each Activity. To make that happen, in each Activity.onStart() and Activity.onStop() implementation, I have logic that invokes Activity.bindService() and Activity.unbindService(), respectively.
Well, all of this works fine, but it feels awkward. Is there any other way to make sure the Service is continuously running and bound to all Activities without having to re-invoke Activity.bindService() and Activity.unbindService() for each Activity? Should the Service in this case be declared as a stand-alone process?
Also, my Service starts a separate thread, but never stops it. Should my code stop the thread? Is there a chance the thread could be orphaned? Starting / stopping the thread with OnUnbind / OnRebind seems like overkill.
Create a base Activity and call bindService in onStart, unbindService in onStop.
public class BaseActivity extends Activity {
#Override
public void onStart() {
// ...
bindService(intent, serviceConnection, flags);
}
#Override
public void onStop() {
// ....
unbindService(serviceConnection);
}
}
This will make sure every activity that extends base is bound to the service.
When last activity is unbound from the service, it will be stopped. If you want to avoid that, call startService first, and then bind to it. This will prevent service from stopping even if you don't have running activities.
Should the Service in this case be declared as a stand-alone process?
In your case, you don't need a separate process for your service.
Also, my Service starts a separate thread, but never stops it. Should my code stop the thread?
If you want to stop your service, you should stop your thread because thread is a GC root, and all objects accessible from it will remain in memory. So, infinite thread that is not used is a memory leak.
You can implement threading different ways depending on your requirements. You can either implement a regular thread in your Service, or a ThreadPoolExecutor or a Handler. Pick a solution that fits to your needs.
You can start your Service in your custom Application class. This way the service will be started only when your application is started.
For example:
public class MainApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
starService();
}
public void starService() {
Intent i = new Intent(this, YourService.class);
this.startService(i);
}
}
While the other answers ere good, you might want to ask this:
"Does this service needs to keep on running while the application is not, and will not run?"
If so: create as an independant serviceIf not: extend a helper class that implements the bind/unbind and have Activities extend that.
Im using the Parse SDK, and at times, after running a few queries one after the other, all calls to Parse just get blocked and I need to restart my app. ( Log: http://pastebin.com/qk6jvtBb )
Usually a single operations involves these FOUR things: Save Object; Make Query; Save Installation; Send Push (im gonna keep the code really specific)
...
pObject.saveEventually();
...
pQuery.getFirstInBackground(new GetCallback<ParseObject>()
...
pInstall.saveEventually(new SaveCallback()
...
pPush.sendInBackground(new SendCallback()
What I want to know is. Should I use sendInBackground for all or saveEventually for all or should I run each in a separate Runnable with its own Handler?
I would recommend if all of the operations are specific to one task, then put it all in an IntentService, do nothing in the background.
so your code would look like this
public class MyClass extends IntentService
{
...
#Override
protected void onHandleIntent(Intent mIntent)
{
try
{
pObject.save();
pQuery.getFirst();
pInstall.save()
pPush.send();
}
catch(ParseException e)
{
//handle errors here DEBUG
}
}
}
The benefit to doing this is that your parse operations are executed one at a time, sequentially, and on a background worker thread. You won't have to worry about four/five different parse sdk calls running at the same time.
Remember, put the IntentService in the manifest. Start the IntentService with an Intent. No need to call stopSelf() when you are finished with your parse sdk operations. You will have to bind the service to your activity, or send a broadcast to let the activity or fragment know that the operation is complete.
I'm having some problems figuring out how to properly organize a particular bit of android code.
This is the architecture of the code: Inside of an activity's onCreate, addService does some work via bindService, and getServices can be run only once the onServiceConnected methods have successfully completed:
public class MyClass{
List<IBinder> binders = new ArrayList<IBinder>;
int stillSettingUp = 0;
public void addService(Class<?> cls) {
//Adds a binder via bindService
ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
//Callback for service being successfully started
binders.add(service);
stillSettingUp--;
}
};
//Increment count of the number of services being set up
stillSettingUp++;
Intent intent = new Intent(context, cls);
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
public List<IBinder> getServices(){
while (stillSettingUp != 0) {
Log.w("", "Waiting for services to successfully connect... " + stillSettingUp);
Thread.sleep(1000);
}
return binders;
}
}
Here is the hitch: the second method requires the onServiceConnected functions to complete. The onServiceConnected functions can't execute until the entire onCreate function completes (since they are events that are tacked onto the end of the main loop, and can't be executed until the current event finished), and so the system deadlocks.
Is there a way to force the other events on the UI thread to process, or a better way to orchestrate the code? I'm trying to avoid running an AsyncTask every time I call these two pieces of code together, as this requires exposing threading requirements to the calling code. This is difficult, however, since you can't force the service connection callbacks to execute in their own thread. Any suggestions are welcome.
It looks like what you need is to execute your 3rd function on the UI thread as soon as both your 1st and 2nd functions have completed. So why not to use AsyncTask and put your 1st and 2nd routines in doInBackground() while putting your 3rd routine in onPostExecute()
Here are my takeaways from my question:
1) If you ever have to depend on data from an Android callback, you should not block, since Android callbacks aren't posted to a separate thread, as in other programming paradigms. You should instead gracefully move past the point where you needed the data, possibly reattempting the data access in e.g., a polling thread.
2) You can also pass in a runnable to be executed after the service is connected. This could get very messy, however.
3) DON'T USE TOO MANY SERVICES. It's typically much easier to just use one or two services than it is to use a bunch of services that talk with one another. I rewrote this set of code, and it's 20x more maintainable now that I'm not dealing with bound services constantly.
I Need some help here, I have a service which I can start or stop whenever I want and using the onStart() command to pass some extras using putExtras() from my activity
But I need some serious basic instructions on how to interact with the already created service.
Please don't refer me to another webpage which already have some implementations, just give me the needed code to interact from my UI activity to the service:
something like this:
public class myActivity extends Activity {
Object ReceivedObjectFromService;
onCreate()
{
some stuff here
myMethod()
}
public class myMethod()
{
//do some stuff with the ReceivedObjectFromService
//Don't know how to call this method from the service btw
}
please some help, I don't understand the tutorials on how to interact service to activity or viceversa
Interaction with already created service is no different to starting a brand new service. You just simply call startService() so your client code is no different.
Now, the part which is different is the service itself. In your service, onCreate() must start a background thread or a timer to carry on doing a work. onStart() will receive all startService cases and must in fact add the data it receives in the Intent to an internal list or queue and then in the timer's callback start processing from this queue.
Now you can pass any messages or data you want (even closing the service) using startService and passing data in the Intent that your service understands.
Hope this helps.