I'm re-inventing the wheel here, but as I'm a beginner programmer I'm curious as to the best way to do this...
As part of an Android app, I'm developing a very simple media player. It plays the file, and I want a m:s timer, so the user can see how far into the file they are (e.g. "04:56").
I'm probably missing the obvious, but what's the best way to do this?
One way would be to generate a new thread which sleeps for 1000ms, then calls MediaPlayer.getCurrentPosition() and updates the UI. However, this seems slightly ridiculous - my thread isn't guaranteed to come back every second, so I'm going to be displaying an inaccurate time. There must be a better way of doing this?
Educate me (or link for me).
Just use Handler#postDelayed() or View#postDelayed() to do your once-a-second updates. This saves you from having to fork a thread, let alone clean up after it.
Here is a project using that specific technique for your desired purpose: updating a time counter based on MediaPlayer progress.
One alternative might be to start an independent timer when the music starts. Have it "sync" by calling MediaPlayer.getCurrentPosition() once every five seconds or so to ensure that the time remains accurate.
Related
I have an app that has quite a large number of handlers in it and some of them seem to be stopping randomly, and as luck would have it, its the more important ones. Is there a maximum number of handlers than can be running at one time or is it more than likely a problem with the code that some of them are not being reset?
Please do not ask for code, the project is huge, >20,000 lines of code so posting every instance of a handler is not feasible, I just want to know if there is a limit to the number of handlers you can have running at any one time.
I think there is no a limit but If there is too much work to do in one time Android kills threads/handlers.
Instead create too much handlers try do it like this:
Multiple threads
I am working on an application that Looks similar to the Google Play App (swipe view with gridviews inside the fragments, in addition data in the gridview [image + text] is retrieved from a remote server).
My problem is with background tasks. I can’t decide what to use for retrieval of data from the internet. Mainly I am trying to decide whether to use AsyncTask or manual threading.
Of course it would be easier to implement AsyncTask, but after some research I noticed that many people find it limiting.
In my particular case, I want to download data from the internet as Json Objects, parse them and display the data in the gridview. The gridview would have up to 30 items, each item contains a thumbnail and 3 textviews. In Android documentation, they say that AsyncTask is suitable for short operations (few seconds at most). Would filling up to 30 items be considered as a short operation?
I want the data to be fetched concurrently. Also I want to support Android phones from API 8 and above. I read that for different APIs AsyncTask behaves differently (serially or concurrently)
My question is: Is it appropriate to use AsyncTask for my app? Or do I have to do everything manually? Is ThreadPoolExecutor a 3rd way to do this? Is it easier than manual threading?
Any advice would be appreciated, I can't move forward in the implementation without deciding on this issue.
Thanks in Advance!
My understanding is that the comment about using AsyncTasks only for short operations is aimed more at not expecting the same views to be available when a long operation finishes. For example, if a user leaves the app and comes back or the current activity goes away for some reason. Typical ways around this would be to use a Service and start up a plain old Thread there, then send some message telling the current Activity to refresh when the operation is done.
The download and processing of your data is likely to be the longest operation. So I'd use that as a basis for whether this is short or long. If you don't care about persisting data at all and don't mind restarting downloads if a user leaves and comes back, you can just use an AsyncTask with very little thought.
If you are using a GridView, you should only ever be populating enough views to for just over the number displayed on the screen at one time.
I'd say that AsyncTask is fine in your situation assuming it's a few kilobytes of data and not megabytes or hundreds of kilobytes. Megs of data, I'd say move to a Service with a Thread. Hundreds of k, is a toss up.
Also, take a look into Loaders... if you want to see an alternative that is better for this kind of loading.
When attending DroidCon in London last year, a presentation brought to my attention why using AsyncTasks for loading data from the network is unreliable.
This presentation was about the RoboSpice library.
The site also has a very nice infographic explaining why exactly AsyncTasks are unreliable and what RoboSpice does to amend these problems.
Disclaimer:
I am in no way affiliated with RoboSpice, nor have I ever tried it. I was just impressed and convinced by their presentation that it's a tool worth trying.
Friend, I am working in a project exactly as you need, and to support API 8 and above you should use Asynctask to download anything or you will get a crash for API 15 and above, because it won't even let you run your app without AsyncTask even for short operations.
So as I almost did everything that you need and it is working very well for API 9 above, you should use Asynctask, I´ve implemented SherlockActionbar, EndlessAdapter and ViewPager all with AsyncTask, so go on, if you need more help just ask again later.
After finishing coding for my app, I started to get into the optimization part. The biggest bottle-neck that I face here is loading of my app when I click on it.
It takes around 15 seconds, which it should not. The splash screen shows up for more than 15 seconds, which might make the user feel that the app has crashed. How to optimize it?
Also, what are the android optimization techniques/hacks?
Any books/blogs/answers would help. Thank you!
Take a look at this android documentation, which describes how to design your app for performance. This video from Google IO explains how to create smooth applications.
Do you really need to do everything you do before the user can enter the real application? Maybe you're loading too much. Maybe you're doing one particular thing wrong. 15 seconds is really a long time. There's almost nothing I can think of that should take that long to get to the screen which the user has to see.
Rule of a thumb - do not perform long runnung tasks in onCreate() and onResume(). Do as little as necessary there, and perform long running tasks in separate thread. When thez are ready, you can use intent to signal your activity that new data us there
I still haven't really wrapped my head around synchronization. I know it's there, I know why it's used and what the idea is behind it, but Im lacking the practical skill and real world examples to understand exactly how it works and how it's implemented when several activies are trying to read/write to the database at the same time. Do you share your objects through Application, or is the system intelligent enough to synchronize various objects of the same type?
Perhaps a Content Provider is a better way to go as I understand that has built in sync.
I digress though.
Im still confused over database activity. Remember that I have a service running every 60 seconds in the background reading the same table an update function is writing to. Yes Im looking to change this, but right now I want to understand database handling in Android more and work out what's happening.
If I have a loop such as:
db = provider.getReadableDatabase();
while(theres_still_work_today) {
do_some_calculations;
update_database;
}
provider.close();
this works fine as a standalone. If I try and place this in a thread, I get errors galore about locking. But when run like this:
while(theres_still_work_today) {
do_some_calculations;
db = provider.getReadableDatabase();
provider.close();
update_database;
}
I find that bizarrely, this actually seems faster, and gives no locking issues.
Am I just being incredibly lucky that I don't get two events triggering at the same time causing a lock? Is there some kind of timeout built into database handling in Android/SQLite?
I don't understand why the last bit of code should work OK, and why it should work faster?
Im not entirely confident about the Android Emulator though. If I use the first option with a single open/close outside the loop, sometimes I can get through a long long loop fine even though the service triggers in the background.
Other times it crashes on a whim.
I also don't know why "isDatabaseLockedByOtherThreads()" does not report that it is locked by other threads.
Any advice?
Thanks
Simon
I've recently begun experimenting with a mediaPlayer instance in my Android app. I implemented a couple different beeps for feedback to the user. Now, when I implemented an audioTrack (for a completely different purpose), I discovered that it pretty much sets itself up as a separate thread automatically (as far as I can tell). It certainly appears as a separate thread when I run my code in the debugger:
Thread [<17> AudioTrackThread] (Running)
My question is: Does mediaPlayer do something similar? My first guess is that it does not -- or I would see thread descriptions in the debugger, right??
Anyway, now I've got to questions:
1) Can I set up my mediaPlayers as separate threads and still have them work right?
2) Does it make sense even to try it?
Thanks,
R.
MediaPlayer will still work like its supposed to in a thread, I've done that before so I could still do everything asynchronously without using the callbacks. I wouldn't spawn more than one of them though they use a lot of resources.