I'm writing a XMPP Client using SMACK.
So when I want to update my contactList - the ListAdapter.notifyDataSetChanged requires to be run in the UI thread, but obviously the SMACK Library uses Multithreading on the RosterListener (which in fact is a good thing). But here is the problem: to run s.th. in the UI thread, I need a valid context.
But how do I get it? Passing the Context of the Activity down to the register function of the RosterListener was the first that came to mind - but I have some functions in different classes there before I even get to the register function, and I don't really like it to pass the context over and over again until it finally reaches its destination, where it will be used.
I guess, I'm not the only one, who has encountered this problem, so how would you solve it?
Maybe a Singleton, just to save this one Context (in my opinion an even less favourable idea...)
Or is maybe my whole design flawed?
Is there a possibility to get the UI thread from anywhere?
Bottom line: I don't really have a clue how to handle it, at the moment I'm passing the context as argument through multiple functions, but is there a better way to do it.
Thanks for any help.
Put XMPP code into Service and then send broadcasts. Interested Activities can simply register for those broadcasts. That way you'll never again worry about UI thread and availability of Activity context.
I found a neater and more modular way of doing it. For this you need to have defined an Application Context. Once you have that, you can call RunOnUIThread from any class library without the mess of having a reference to the Activity.
From anywhere within your class library call:
Handler handler = new Handler(Application.Context.MainLooper);
handler.Post(() => doStuff());
Please bear in mind that this is written in C# as I use MonoDroid, but I believe it is very similar to Java.
For how to create an ApplicationContext look at this thread
I do not get what exactly you try to do but if you are in some thread and you want to shitch back to UIThread than
Looper is your solution
http://developer.android.com/reference/android/os/Looper.html
Reading you, I get a feeling like you are working with callbacks. Smack or whatever that is is calling you back from a worker thread, and you want to post to the main UI thread when that happens.
In my experience, callbacks can always be associated to a custom piece of data, which you pass when registering the callback, and receive when you are actually called back.
In your context there are two approaches which I consider to be poor design:
using any kind of global thingy, call it a singleton if you like
let your Model expect and return the (Android-and-UI-specific) Context
Instead, I would create a small interface which is implemented by the Activity, have the Model accept an instance of this interface, and yes pass it over the different layers until registration.
The methods exposed by this interface will be called asynchronously, which you could document appropriately, to indicate that runOnUiThread() or similar must be used.
This way, you're not exactly passing the Context (which is a platform and UI detail) all over the place and into the Model. Plus, you avoid global/static data, which leads to various problems, conflicts and other memory leaks.
Related
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.
Suppose I have an object I've created. We'll call it MyObject.
I'd like to be able to save MyObject to a database's corresponding table. I don't want this to happen on the Activity's main thread. Easy enough. I created an AsyncTask to do this.
However, my application also has an IntentService used to sync data between the device's database and my cloud database. I'd like to save MyObjects that have synced down from the cloud to the device's database from here, too. However, I do not wish for this to happen asynchronously in the IntentService. I want it to happen on the IntentService's main thread.
The purpose, obviously, is to modularize this code so it doesn't need to be duplicated.
How can I modularize my save code so that it can be called both asynchronously and synchronously?
I suspect I will create a saveMe() method inside the MyObject and declare it a static. From the IntentService, I simply call saveMe(). From an Activity, I will launch an AsyncTask which passes in the MyObject and then calls saveMe(). Does that sound right?
Besides the static that sounds good to me, don't you wish to access instance variables?
I don't know how your application is designed in general, but I'd probably go for one of the following patterns:
a subclass of Runnable (or Callable if you need return values and/or exceptions) that handles saving in general, with a suitable factory or constructor. You can then run these tasks directly or on background threads.
instances of objects have a method to save themselves (this is what you described), and these methods are used by synchronous or asynchronous code.
instances of databases / storage classes have a method to save MyObject instances, assuming they have a common parent class where you can put that code, and these methods are used by synchronous or asynchronous code.
The exact pattern depends on the application you're working on imho.
When I'm in a situation where I sometimes want to do something synchronously and sometimes asynch:
I tend to implement an IntentService with a public static method to do what I want usually called blockingX where X is what it does. This way, if I want to do it synchronously, I call the method directly. If I want to do it on a background thread, I send the service an intent.
I have strictly separated the layers between different parts of my Android application.
At some point of execution I am updating my data from xml service on Internet. That updating takes up about 10 seconds and is done completely in the background - meaning the user interface of an application works fine. However further calls to my class (later - DataManager) which is responsible for data updating (after update has been started but not yet finished) makes my application crash. NullPointerException is thrown with objects which NEVER are null.
So I assume that only one Thread can use my DataManager at one time and calls to DataManager from other threads ends up in exceptions.
I tried various combinations of putting 'synchronized' keywords near sensitive methods but it seems that when update is executing - NOTHING can use ANYTHING from my DataManager.
BTW other classes which are related to DataManager during the execution also seem to hold null objects.
I guess I am just missing some kind of design pattern which is used to deal with concurrency problems and maybe anyone can suggest me something?
I had trouble dealing with using the Apache http client because of threading issues and I think your issue could be similar in that respect. What I ended up doing was setting up a callback scheme. This may or may not work for you, of course.
This may seem a bit Rube Goldberg-like to you, but it worked for me.
I would have my UI thread call my data manager object with a method that spawned a thread to go and acquire the data. The method's return value is an object that would EVENTUALLY have the data in it. I would have my activity extend an interface, something like "DataCallbackInterface", with a method that the thread would call after it acquired the data (i.e. the last line in run()). Since that call will inherently be within another thread, you'll need to use a Handler to run anything useful in your implementation of the DataCallbackInterface method. When that method is called, you will know for a fact that the data is there and not rely on any strange synchronization flags to get it right.
In my Android application, one of my activities includes instantiation of other classes of mine.
Some of the classes need to write to the screen. I want to keep all the layout interaction at the top level.
So, I created an Interface which includes a list of methods that can be called to output to the screen. I then Implement this interface in the main Activity.
Finally, when instantiating the classes I pass "this" to the constructor and it is saved and used for the callbacks.
My question is: is there a danger of memory leaks due to me passing the Activity object itself into one of its objects?
I would look into the standard Android Handler mechanism for this (also supporting custom callbacks for UI changes).
Here's an example of a handler defining a custom callback to handle UI changes :
http://developer.android.com/resources/samples/TicTacToeLib/src/com/example/android/tictactoe/library/GameActivity.html
As long as you can ensure that your "this" is scoped properly, you should be pretty safe, however, as soon as you start passing activities around to other classes, it does leave the door open to potential memory leaks, as pieces of code can get a hold of that instance now and prevent it from being garbage collected in time where garbage collection should have occured on the object.
If I understand your question correctly, you have abstracted some UI interaction functionality in to a class and decorated your activity with it.
The simple answer to your question is no. Although you pass an instance of "this" to the object, the scope of the object itself is governed by Activity. In fact android framework passes around context, not very similar to what you do. I believe we can all agree that Activity has a very limited lifetime.
The second point I wanted to make is, about the whole methodology itself. Android provides mechanism to post back to the main thread to perform UI interactions. (post or asynctask etc..) You should use one of these mechanism to make some changes to UI (in the main thread). So my question is, could you not write an anonymous inner class to perform this operation using asynctask, especially if this functionality is unique only to this Activity.
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)