Here's my set-up; I have a news app. This app loads a few listviews from local storage (I'm abusing sharedpreferences for that, but if that's good practice would be another question). I want to be able to update this local storage smoothly.
My first approach was to make a button trigger a service, which did the trick. But I also wanted the service to refresh the activity when it was done. I wasn't able to do that.
My current approach seems to work, but not as smoothly on 3G. Activity A shows a 'Loading' box, then launches activity B and destroys itself. Activity B also shows a loading box, does the downloading, then destroys itself and relaunches activity A with the new content.
However, this last approach makes the screen go black for a few seconds in transition from A to B when on 3G.
For the sake of visual smoothness, I'd like one loading popup to display continuously. When done, the activity should be refreshed.
Does anyone know how I can achieve this?
I hope my explanation was clear enough. Otherwise, I'd be happy to share some code with you.
Thanks a lot in advance
Looking at the code you linked to in your comment, you are doing too much work in the onCreate method of your activity. onCreate should be kept lightweight in order to display UI to the user as quick as possible. You probably want to move the bulk of your Activity setup to the onResume method. Furthermore, anything that blocks the UI thread (like fetching and parsing data) should be done on a thread. Look at using AsyncTask (http://developer.android.com/reference/android/os/AsyncTask.html) for this purpose in your application.
Related
So, for my Android course this semester we're making an app of our own choosing, and due to a lack of ideas I decided to go with a text-adventure styled game. Nothing too complicated, I know. I'm making sure to be creative and incorporate a lot of different functions of the phone, such as the accelerometer and the camera. But I digress.
I've started planning out how the app should work, and how I should go about coding it, but I've come upon an obstacle fairly early that I need to find a solution for. I'm planning on creating it so that the player is sent from activity to activity, which I think is the best way to go about it, unless I do an endlessly scrolling activity that fills out as the player progresses. And thus, I need a way to make it so that when the player closes the app completely it will "continue" on the last activity before shutdown, so the progress is saved in a way.
I'm not sure if this is possible to do, and if so, are there any other ways I can achieve the same sort of result?
There is no way that you can change your starting activity programmatically. You can save the activity that you want to start with in a file and redirect to this activity from your main activity every time your application starts (on the onCreate() method of your main activity).
As it says here.
As someone has suggested, save the current state (ie: what Activity is currently shown) in SharedPreferences. When the user launches your app, the root Activity (the one with ACTION=MAIN and CATEGORY=LAUNCHER) will be started. In onCreate() of the root Activity, read the saved state from the SharedPreferences and launch that Activity immediately.
I'm trying to implement the MVP architecture in my app.
However, after reading some blogs and viewing some sample project samples, I'm not sure I completely understood where is the right place to detach the view, and what should be done once the view attached for the second time after an async operation.
Most of the examples I saw, just sum it all up with a view's null validation check after an async call.
I'll try to make my point clear with an example - Login/Registration by phone number (The main idea is the important thing, and not the example itself)
There is an activity which display a fragment - LoginFragment.
The user enters his phone number and tries to login.
If the user exits - he should get navigated to another activity (after entering the code received by sms..)
If the user doesn't exits, he should get navigated to registration process - RegistrationFragment.
If there was an error, a dialog with error message should appear, ErrorDialogFragment.
Now, in a happy flow where the user presses the login button and waits until the process complete, all good.
But, in a less happier flows (not so frequent ones, but definitely can't get ignored), the user presses the login button and after that presses the home button or alternatively gets a phone call.
In scenario 1, where we attach/detach the view in onCreate/onDestroy, once the async login operation finish and we should replace to RegistrationFragment or show ErrorDialogFragment, there is a chance we will meet the famous IllegalStateException:
getting exception "IllegalStateException: Can not perform this action after onSaveInstanceState"
In scenario 2, where we attach/detach the view in onResume/onPause, once the async login operation finish we won't be able to replace fragment or show a dialog because the view is already detached.
In this case, I'm not sure what is the right thing to do.
Should we go with scenario 1 and commit the transaction with commitallowingstateloss?
I'm afraid it is a bad idea.
Or Should we go with scenario 2. In this scenario, we should act accordingly when view attached again, which means saving states (RegistrationRequied, ErrorHasOccured, LoginProcessStillRunning, etc..) in the Presenter/Interactor.
Can someone can shed some light regarding this?
Thanks in advance!
Oh the joys of the Android lifecycle. I feel your pain.
In my personal experience, resorting to commitAllowingStateLoss is usually a symptom of trying to update your Ui (View) while in the background (and as you note, the ui may be destroyed).
What I would suggest is that you don't try to update your ui without checking if the activity has been backgrounded (onStop or onPause depending on the situation). If your ui has been backgrounded, remember the changes you need to make and do them when your Ui is reconnected (onStart or onResume depending on the situation).
In essence I'm saying you should follow Scenario 2. And yes. You will have to save quite a bit of state somehow.
Unfortunately this isn't easy and there are many approaches to doing this ranging from using event buses, all the way through to using RxJava.
Every approach has it's advantages and flaws and they are all really too complex to discuss in detail in a single post.
However, I have a blog post I wrote some time ago on a way of doing this in a way that doesn't require additional libraries.
It's a little out of date now, but it may give you some ideas: A Simple MVP aproach for Android
All the best.
Kind regards,
Chris.
I'm trying to create a general help for all of our companies Android applications and it should work like this:
User is in Activity/Fragment A
There is a help icon anywhere on the screen
On its explicit click, or during a user interaction flow, Activity/Fragment A freezes, and initiates Help fragment, passing a key only to the Help fragment, so that Help can retrieve data from server and display it in whatever format it wants
At the end of Help, user clicks a button.
Help activity should be closed
Activity/Fragment A should become alive, but not from the beginning, from the last state it had, preferably, from the last line of code it was executing.
In fact I can say that I need a full-screen dialog (web or Windows terminology)
I've seen other questions, which explain about singleTask and singleInstance activities. However, the problem is that the Help activity knows nothing about the parent/initiator activity. Thus I don't want to use Intent. I tried using finish without starting an intent. However, by just finishing the Help activity, Activity/Fragment A doesn't get onNewIntent and won't be notified to resume code execution.
I'm stock at this point. What should I do? We have successfully implemented this architecture in Winodows and Web platforms, and we're pretty content with this design. Yet I would appreciate any design tips in Android world too.
You could use DialogFragment, check a tutorial here codepath/DialogFragment
Please explain what you mean by "don't want to use intent".
Have you tried starting the HelpActivity using startActivityForResult?
It provides a onActivityResult callback to the activity that made the call to it.
I was wondering how about the different ways in which an app can be opened, some tasks performed on the main thread and then be finished. And which way would be the best for this purpose.
I thought using an asynctask and putting the thread to sleep for sometime should be helpful and in postexecute perform the task that i want. But I am pretty sure this is a very expensive solution.
For example, If I want the app to click a photo on its own when the app is opened. The app needs to be opened and then wait so that the camera resources can be loaded properly. Once this is done the photo is clicked and once the photo is saved the app will finish.
Please provide some links if you can so I can read up and understand these concept better.
What are the better ways to go about solving this problem than using thread.sleep()..
Please share any good methods..
Thank you.
if I understand what you need (I'm not sure) you can use broadcast to cominicate between tasks
I have a ListActivity that instantiates an AsyncTask, makes a call to a web service, and populates the ListView with the results.
How should I handle device rotation while the AsyncTask is still running? Should I cancel it, save off whatever data I need, and start a new one when the ListActivity is recreated? Does Android somehow already handle such a case?
It seems like what you require here is a service, not an Asynchtask - as you are running a long query that should persist and deliver it's results the same way regardless of orientation.
BTW, killing the Asynctask is NOT straightforward - best not to go there at all, but let a service run truly in the background.
Do you require that your ListActivity is recreated on orientation change? I would expect that your users would not want that - but would rather have the populating of the ListView carry on.
I have an app that does a series of HTTP GETs and POSTs within a string of AsyncTasks, without restarting the activity each time the orientation changes. All you need is a line similar to the following in your manifest.
android:configChanges="orientation"
See the docs at http://developer.android.com/guide/topics/manifest/activity-element.html
Torid's suggestion of overridding the config changed handler works in most situations. However, I've found that some manufacturer's devices still recreate the activity, even when you've done this (I've seen 1 HTC phone that does it so far).
The proper solution is CommonsWare's answer in the following link:
Background task, progress dialog, orientation change - is there any 100% working solution?