I would like to make use of the universal tween engine in my pure android app, and understand that I will need to put a loop somewhere which will update the tweenmanager every frame. I have used this before in game projects where i have access to the game loop provided but in the case of a pure android application, where would I create this loop and what is the best way to handle this as my app is opened/closed/paused/resumed etc?
Am I best creating a new thread in the onResume method for each activity and starting the loop there and ending the loop in the onPause method? or is it better to create a class that acts as a sort of "Activity manager" and is always available? if so how would I do this?
I found some useful documentation on this at https://code.google.com/archive/p/java-universal-tween-engine/wikis/AndroidUI.wiki and It seems the 'correct' way to achieve this is to create a new loop for each activity in onResume() and end the loop in onPause()
There is an API available starting in API level 16 called Choreographer. This is the thing that keeps the main thread pumping events at 60 frames per second. You can register a callback to be executed with the next frame, then within that callback, register to run it again at the next frame. This is the most reliable way to get called at every frame with near-perfect timing (as long as the main thread is not being blocked in a way that would case frame loss).
Your callbacks will all be called on the main thread, so be careful yourself about blocking the main thread. So keep your work super fast.
Related
I know it sounds crazy that someone is using runOnUiThread inside AsyncTask. Somehow, it is working for me but I wanna know if it is an acceptable and robust approach or not. Here is the scenario:
I have an app in which after successful login, user is rendered to next screen. In this new screen, 3 different methods are loading different types of data from a web server. These methods are:
getMembersForList() : It loads the list of community members and shows it in a listview.
getProfileData() : It loads the profile of logged in user and shows his name , image etc on the screen.
getNotificationCounts : It loads the count of new notifications for the user.
I applied 3 different approaches for it :
(1) Calling all 3 methods simply in onCreate i.e. no exclusive thread is being used for any of the methods . In this case , the transition from login screen to this screen becomes very slow and black screen shows up for some time before this activity shows up.
(2) Calling getMembersForList() on UI thread and the other 2 methods on exclusive threads. In this case transition becomes fast and list shows up quickly but Notification counts and username etc. don't show up because WrongThreadException occurs saying that this thread can't touch other thread's views (TextViews for username, notification count etc. which are declared globally) . The same thing happens when I start these threads from an AsyncTask as well.
(3) Calling getMembersForList() on UI thread and then starting an AsyncTask in which the other 2 methods are being called in "runOnUiThread" inside doInBackground() method. This solves both the above issues. Now the screen transition is faster and the WrongThread exception is also not occuring.
So far the approach-(3) is working good for me but I am not sure if this is the right way to do it because runOnUiThread and AsyncTask are 2 completely opposite things. Can anyone please clear my doubts about this scenario. Thanx in advance.
Yes, use-cases like this are a big reason why the runOnUiThread() method exists in the first place. The idea is you allow your background thread(s)/AsyncTask instance(s) to run your lengthy operations in the background, and then provide a simple hook that they can use to update the interface when they have the result (or at arbitrary intervals, as different pieces of the result become available).
As long as that's what you're doing, then your usage is fine. What you want to avoid doing is performing a lengthy operation on the main thread, either directly or indirectly by passing in some lengthy operation from a background thread.
Of course you don't have to do it that way if you don't want to. You could use postExecute() instead. Or you could store the result somewhere and then use any sort of message-passing API to notify the main thread that the result is ready, and so on.
I would advice to run all the 3 calls in the asyncTask, and update the UI in the postExecute() of the AsyncTask after the background taks is complete, postExecute runs on UIthread so you need not call anything explicit to run them on UIthread.
So, I'm working on a barcode decoder, which once we have the barcode goes to multiples API over the internet to decode what was just scanned.
The thing is that I have to link some XML parsing together, and I don't know if I'm doing it right.
So, once the barcode is scanned, my program calls an ASyncTask which goes over an API to retrieve the product name. Once it has the name, I want it to call another ASyncTask. I know this is possible by instantiating an ASyncTaks in the onPostExecute() of the other but, I think this is wrong, because it's like boxes within boxes.
So isn't it possible/better to instantiate my second ASyncTask inside my main Activity, and make it wait until my first ASyncTask is finished ?
(english isn't my primary language, I hope I made myself clear).
I think it's absolutely legitimate to start the second AsyncTask in the onPostExecute of the first AsyncTask, Mixing both operations is a bad logical idea, As "The Offspring" said - "You've gotta keep 'em separated"
If you don't want it to be directly inside the onPostExecute itself, set a handler to execute it in the activity and call this handler from onPostExecute.
And last thing - If you have a lot of logic - move it to a separate file, don't keep it all at the same file.
In situations like this it might be better to batch long running operations together in one AsyncTask.
Another option is to use the Loaders API, this makes chaining tasks much easier http://developer.android.com/guide/topics/fundamentals/loaders.html
You can go for another approach if you are facing often a situation like this. That is to merge requests and operations inside of runnables/callables and to manage them separately within say a queue for instance.
Here is a nice approach.
http://ugiagonzalez.com/2012/07/02/theres-life-after-asynctasks-in-android/
I am using Eclipse to develop an Android application that plots Bluetooth data.
I am using open source code, which has an existing solution that I want to extend and not replace to solve my development problem as stated above.
The open source code has a very nice and solid background thread that among other things continually logs BluetoothData to logcat even when I switch to a new activity.
Currently I have a solution which I am concerned about: I simply leverage a background thread method that writes to logcat to call a static plotData() method in my Plotting Activity. The result seems good. I get a nice plot. It clips along in real-time. Looks like an oscilloscope.
But I have received negative feedback about using the existing background thread coupled with a static method to plot the BluetoothDate. It has been suggested that I use a new thread, or add a handler, or use Async Task, or AIDL to solve my problem.
I have looked at all these solutions without success. Nothing seems to work like my static plotData() method. That is to say the existing background thread calls my static plotData() method which results in a real-time plot that looks great.
But I am still concerned about the negative feedback. I simply want to extend my existing background thread solution which I have done by having it call a static method to plot the data.
What are the problems I might face with this approach? Thread safety? Deadlock? I don't know.
Why do people keep suggesting that I create a new thread, handler, Async Task, or Service to solve my problem when extending my existing thread to call a static method seems to work just fine?
Any suggestions? What are the problems with extending the existing thread to use a static method to plot the data in real-time?
Anyone who says that you should use AIDL for this is a loon who should not be listened to. :) Also someone saying you need a Service if you don't want to have your background thread running when the user is not viewing your activity.
I'm not sure what you mean by "writes to logcat to call a static plotData()." You should write to logcat only for testing. Writing to logcat doesn't cause a call to any Java method.
If you are calling a static plotData() method on your Activity, you need to be extremely careful with this: first because it is difficult to figure out what activity instance should be called from there (it may go away at any time from the user finishing it, or be recreated as a new instance when the configuration changes, etc); and second because you can't touch your app's UI/view hierarchy from a background thread without risking that you corrupt its state (since the view hierarchy is single threaded).
The general model one does for this kind of thing is to have a background thread doing some work, generating the next data to display. Once it is done with the work you send a message to the main thread to have it display the new data. AsyncTask can be a simple way to do this, it takes care of the underlying message sending and threading. You can also implement this yourself, at some point having a Handler that you post a Runnable on or send a Message to that once executed on the UI thread will update your view state.
(Of course if you are using a SurfaceView, the whole point of that is to allow drawing to it outside of the main UI loop, so your background thread could just draw directly on to it as needed. Basically that is like writing a game.)
I read a lot about handling rotation in android applications, but I still have so many questions and need to much to understand.
Let me explain my problem or implementation, that I'm using now in my application.
If an activity will be opened, a get request will be sent to server. This request will be executed in a Thread (new Thread(...)) and if request was completed, activity's ui will be refreshed.
But what should I do, if the user rotate his device?
By default, the activity will be destroyed and request will be started again and start a new thread, but the thread of destroyed activity may be still running.
I guess, it's a quite wrong way, I have now.
But what is the best approach, to handle this?
Probably is the best way to forbid rotation, but what If I don't want that?!
May be it's the second part of my question:
I saw a video form Google IO. Mr. Dobjanschi suggested to use services and to store retrieved data in content provider. So, probably I can use a service for executing my requests. But should data be replaced every time the get request was completed?!
Well dont know exactly how its done, You can try saving the instance and retrieving the same when config changes with following methods:
I have read about them but haven't really implemented them yet. I hope it can give you some start.
#Override
public Object onRetainNonConfigurationInstance() {
return(myServerThread);
}
private void restoreServerFunctions() {
if (getLastNonConfigurationInstance()!=null) {
myServerThread=(Thread)getLastNonConfigurationInstance();
}
}
You can specify that the activity handles the rotation itself. This is done through adding:
android:configChanges="keyboardHidden|orientation"
in the tag of the activity inside your android manifest. You don't have to actually handle the rotation but this will tell android to not destroy your activity. The base activity class will handle all the rotating of the user interface for you and your thread will be executed correct.
A small side note: if you are doing only a small server task use AsyncTask to execute the call to the server in the background instead of creating a thread. This will minimze some of the programming effort you need to communicate the results from the thread to the activity and update your UI.
One easy way, though I've never tried it. Instead of refreshing the current UI, when the thread finishes, start a new Activity with the just downloaded content. So first, you start an Activity with a blank page (or just the page's frame), then you rotate the blank page as much as you like, then the downloading Thread spawns a new Activity, replacing the blank page Activity with the loaded content page using the current orientation.
I have a main game thread but when the target score is achieved I have an activity that is launched called StageCleared which basically displays the stats to the user of their performance and then they can press a continue button to carry on with the game. This should switch focus back to the running thread that should continue execution, and thus display the game activity (with parameters i update after StageCleared has exectued).
It was suggested I use a package visible object that calls wait() on itself in the main game thread, and then notify() on itself from StageCleared in order to continue execution. My first problem is I can't seem to declare a package visible object that can be seen by all the classes in my package? Secondly, is this the best way to achieve what I'm intending to do or is there a better way?
Many thanks
To enable package visibile, leave the modifier blank:
static boolean mVarname = true;
mVarname is visible inside the package.
I work with a run flag to enable if the loop should do something or just "idle". I, too, dont know if this is a good way to do it :)
Use FutureTask and Executor, check it out in Java API.
It's like, you define the operation and FutureTask, and it'll wait until the task is completed.
Easier than wait()