issue with android.os.Messenger and android.os.Handler with rotation change - android

Im trying to use the pattern of Activity-Service-Messenger to comunicate my Activity and Service. (like explained here http://viktorbresan.blogspot.mx/2012/09/intentservice-and-inter-process.html) Basically it says that i should create a Handler inside my Activity, and then create a Messenger and send that via putExtra() to my Service. The Service would then post messages to the activity ussing the Messenger.
My problem is that if i rotate the emulator, the Handler associated with the Messenger holds a reference to a destroyed activity. This causes not to refresh the interface of the new activity. I tried to put Messenger in onSaveInstanceState(). Eventought i can save the Messenger, the Handler is still referencing my past activity and i cant find a way to retrieve my Handler from the Messenger to set the new activity.
Edit:
Im avoiding to using:
android:configChanges="orientation|keyboardHidden"
onRetainNonConfigurationInstance()
Edit:
I used HalR idea of using a singleton and keep the handler there. It works really good, althought i can see that this pattern implies a careful cleaning of the references on the singleton.
Finally im also testing on the idea of using Activity-Service that was commented by Hoan Nguyen

I'm not sure that its appropriate for this case, but there are many people who have been frustrated by losing their activity when it rotates, or having to set complex stuff up every time they get a new activity.
Some people will create singletons that they use for referencing, then keep the Handler in there.
Others will extend the application class and put stuff in there. If you have a lot of complex things you are wanting to set up once, those are techniques you can use.
Keeping your app fluid and your making your activities independent of one another is a better overall philosophy, so its best to avoid anything global, but sometimes you gotta do what you gotta do.

Rotating the device at least pauses and resumes your activity according to the lifecycle. I think you are aware of the consequences.
Maybe stopping and starting a new service is the only right solution here. i worked as well with global states, but it will just always be easier when, you make every activity independent like a "single application".
edit: ok it's a messenger service... so stopping and starting is not a solution. so maybe you can register and unregister your messengers.

Related

Creating global Runnable?

So, I've implement sync mechanism, that uses Runnable.
The thing with Runnable is, that you have to make sure it's properly created and destroyed in Activity. What happens if you have alot of activities? - Alot of boilerplate code.
Is there a way to create a single instance Runnable for whole application?
Is it okay to initialize it in SomeClass extends Application as its app entry point? If so, how would one solve cases as such: SomeClass.onCreate() will hit even if user receives notification (that would also mean, that sync happens every time user gets a notification - which is terrible).
Why don't you using life cycle aware app component like - LiveData and ViewModel from android app architecture components. This is the best solution with AsyncTask.
With Runnable you don't have any control to stop or resume your execution with activity lifecycle. Because if a Runnable doing task in background it will complete any how and it causes defenitly memory leak.
Another easy solution is you can try using RxJava and RxAndroid, so simple in less code, see this.
And if you still want traditional way you can try this.

How to get the foregrund activity instance?

I try to get the foreground activity for a long time, and i didn't managed to get it until now.
I don't know if it even possible, but i am dont intersted in my app activity only.
There is no data transfer between my service and the activity which i want to get.
I saw lot of questions of this kind but i got nothing suitable for my needs.
I just need to get an instance, not a ComponentName, not decription of the current foreground activity.
I've tried through ActivityThread, ActivityManager, ActivityManagerService (even though i couldnt get his instance too), and so on.
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");// won't help
activityManager.getRunningTasks(rnd);// won't help either
If there is any refelection way, listener or something like that, but not a static field.
Without knowing why you want an instance of the Activity, or other background info. I'd suggest the following.
If you're inside a Fragment, then you can do getActivity() - which will give a reference to the Activity, and you can then cast this as your own Activity.
Otherwise, you might want to consider having a BroadcastReceiver, which can start an Activity for you.
You shouldn't be accessing an Activity directly. If you have methods/logic you need to access, you might consider refactoring them into a helper class.
Edit:
"Your application runs in a secure sandbox environment, so other processes on the system cannot access your code or private data." Take from the official Android docs

Activity, Service and what kind of communication between?

I'm trying to develop an Android application consists of an Activity and a Service. The Activity launch a process on the Service of indefinite duration, which will be closed from Activity. Do not use then the subclass IntentService, but directly Service. Controlled by onStartCommand and OnDestroy.
I obviously need to pass information from the Activity to the Service: the status of the Service and some strings.
I tried to use LocalBrodcastManager, but when turning the devices or when the activity goes in state onPause, the message will lost. I tried to follow several examples, but with little success. This in particular I could not complete it because of some missing information, evidently deemed obvious, but which are not obvious to me: https://developer.android.com/training/run-background-service/report-status.html
I then tried to use Messenger via IBinder ( Example: Communication between Activity and Service using Messaging ), But the program seems a bit complex and I can not able to fit my needs.
What I need is to launch the service from my activity (possibly make binding automatically?, in case of Messenger use), the Service should signal the Activity to be active, then Service records some points via GPS LocationListener, writes it to a file and should point out, again the Activity, the data that is recording, the file size, etc.
What do you recommend to use to pass this information and can you provide to me some example?
I am actually in the midst of a tutorial explaining and comparing many different approaches to IPC in Android but since it's not ready and because you need an easy fix i'll recommend https://github.com/greenrobot/EventBus.
Also feel free to look in an old but still relevant example me and my friends made a while back here: https://github.com/RanNachmany/AndconLab
Goodluck.

Android: How to access/share a Activity bound service with another Fragment?

I have a main Activity that's happily been working with a Service I created for a while now. Recently I've had to add a DialogFragment to my app and although its working nicely as well, I now need to make a call to my Service and pass along more than the usual Intent type strings. Basically I need to pass an array of Bitmaps to the Service, and I don't think it's reasonable to try and stuff them into an Intent.
So I was hoping, without luck so far, that I could bind to the service while the DialogFragement is open so I can make a direct method call to the Service.
Is there any way to do this? So I have to copy the entire ServiceConnection class and bind to it from onStart()? I figured there must be a less messy way to do this.
Thanks in advance.
As there is no code, I assume that your DialogFragment serves to capture some kind of input from the user (Yes/No or something similar), as most dialogs do. If this is the case, then you can simply return the input back to the calling Activity and make a call to the Service based on this input. Another question is where to the Bitmaps come from? Passing an array of Bitmaps from an Activity to a Service doesn't seem a good decision for me, you should probably consider moving the Bitmap retrieving logic to the Service itself, whether the Bitmaps come from the network or from resources.
Most part of my answer is based on assumptions about the design of your application, so if those assumptions go wrong you can post some code or add a broader description of your app and I'll be glad to review my answer.

Android app architecture - where to put REST API call code?

I want to better understand how to structure an Android app where an activity fires off an API call (for example).
I'd currently implement it by putting the API call into an AsyncTask subclass, passing it a reference to the activity so it can update the UI in onPostExecute. But my gut-feel is that this is creating overly-coupled code.
I'm wondering whether instead I should put an API call like that into a service, and use a BroadcastReceiver to update the activity.
What say you, AsyncTask, or BroadcastReceiver?
I usually follow the Local Service pattern. I have a strong suspicion that this is how the official Twitter app works and that this is the pattern most of the Google apps use. This also solves the issue of your app going away (getting killed or going into the background) before the task finishes, or if the phone switches configuration during a background task.
BroadcastReceiver and service is an overhead here. A request to web-service should not go to long. Service is appropriate in case of downloading files or something similar.
AsyncTask way is the right one here. But I would suggest you showing a progress dialog to let user know that your application isn't freezed, but doing some useful work.
See the example here.
AsyncTask is just fine. Only thing you should worry about is referencing you Activity using WeakReference to avoid whole Activity be memory leaked. It isn't overly-coupled code imo if you using observer or events patterns.
I would go with a service only if the call is going to take long, so that the user can leave the app while it's completing.
I'd use the AsyncTask if the task is short enough that it almost wouldn't go ANR if done in UI thread.
(disclaimer: I consider myself a beginner, and I'm expecting comments from more experienced people)

Categories

Resources