I google a lot, but now I decided to ask..
My activity does only one simple thing - it downloads a picture from Internet using AsyncTask.
But there is a lot of problems, that I am not sure, how to solve..
1.] User rotates screen after AsyncTask have downloaded the picture.. How should I handle this screen rotation? Where to temporary save picture to be available after activity recreates?
I don't want to lock screen orientation (android:screenOrientation="landscape") or handle it by myself (android:configChanges="orientation")..
I just want to save the picture somewhere..
I know It can be done by using onRetainNonConfigurationInstance() and getLastNonConfigurationInstance(), but both are deprecated now. Bundle isn't appropriate for images, because it is made for String (Serializable) data. I can save picture to database or to file somewhere, but it is unnecessary. I read somewhere, that it can be done by Loader, but I don't know how? Is it possible?
2.] User rotates screen during AsyncTask is downloading a picture.
I want AsyncTask to continue with downloading. After download is complete, AsyncTask should save image to new (recreated) activity in onPostExecute method.
I think if AsyncTask is inner class of activity, it works..? But if I don't want it to be inner class I have to save reference to activity, for example in variable. But if I send reference to Activity as a parameter of constructor of AsyncTask, and Activity is recreated after screen rotation, the variable in AsyncTask does refer to original activity and so new one doesn't know about downloaded picture and it has to start download again..
Or is AsyncTask bad choice for downloading image? Should I use something else? Service?
So.. How to solve these problems? I am sure a lot of app developers have to solve this too.. But it is all Greek to me:(
When your AsyncTask has finished downloading the image, save it to your application's cache directory. Persist the path to the saved image in a property on your Activity class. You can then override the onSaveInstanceState method of your activity to pass the cached image path to itself during an orientation change. In your onCreate method check the savedInstanceState bundle for a saved image path. If that path exists, do not attempt to re-download the image. Instead, simply load the image from disk.
I've already answered somewhere. I found a very nice example: read this. This example for old APIs.
For new you can use setRetainInstance method of a fragment (if you use fragments).
Related
I'm trying to create an application where there is a need of uploading images from my mobile. In this case, when I open my Gallery and choose a image and come back to my application, onCreate() is called again due to which the TextView, EditText and the booleans which I've used earlier are cleared.
Can you please help me how I can solve this issue.
Your activity is getting destroyed due to memory issue you might be doing some bitmap op or something check it out also try adding large heap=true in manifest
I'm trying to solve this, right now I have a Details Page activity (which loads dinamically from the DB depending on the item that was selected from a ListView). Each Details page can have between 1 and 5 images, which are downloaded from an online server. The problem I have is that the activity is not showing until the pictures were downloaded.
Basically the activity won't show until onCreate finishes. I'm using a thread to download the image so the UI doesnt freeze, My question is, where could I download and set the ImageView to the downlaoded bitmap so the user will see the activity and information straight away after clicking on the list item and then download and set the image after downloaded?.
I tried putting the thread on the onResume but I think it doesnt help either. What would be the best way?
Regards,
George
You need to implement an AsyncTask. Which executes on a background thread and prevents blocking of the main thread. You simply create a class that extends AsyncTask like below
EDIT - Yes, this will display your Activity even before the images get downloaded. You simply call the execute() method of your AsyncTask in onCreate() Have a look at the page on AsyncTasks above for a complete overview. It's really simple to implement you just need to be aware of configuration changes if your AsyncTask has not completed.
You might also want to look into caching your bitmaps in memory to prevent them from being unnecessarily downloaded again.
public class DownloadItemDetails extends AsyncTask<String, Void, ArrayList<Bitmap>{
protected ArrayList<Bitmap> doInBackground(String...params){
//Download each Bitmap here, and add them to a list to be displayed later
}
protected void onPostExecute(ArrayList<Bitmap> results){
//This method executes on the main thread, so after your downloads finish
//You can set your imageviews in your Details Page here
}
}
According to your curiosity to make user happy, I think you have to use Android Universal Image Loader library from Github. This library provide you asynchronous image loading, caching and displaying.
You can also use ShutterBug - Remote Image Loader from Github for same. It also fetch remote images and cache them. It is particularly suited for displaying remote images in lists, grids, and maps.
I have a method in my main class, that fetches some data from the internet. The thing is that after everything is done, if I change the screen orientation by moving the device, everything starts allover again(fetching data while displaying a loading screen). Is there somewhere I could put my method so that if my device's screen orientation changes, it won't erase everything that has been done until that moment? Thanks.
What is happening to you is that every time you rotate your activity is recreated, as per android good practices you should handle your activity being recreated because android may destroy your activity at any point if resources go low on the device. Take a look at saving the state of your activity and how to restore it and the link.
Example using onSaveInstanceState()
You can use a singleton class to store your data.
If you prefer a simpler way you can also put your data as static, so the orientation change will not throw them away.
I think that your Activity is getting recreated again. In that case,it will load again.
1). You can handle orientation change by overriding
public void onConfigurationChanged(Configuration newConfig)
and in your activity declaration in manifest file add the following line
android:configChanges="orientation|screenSize|keyboardHidden"
2). As Aerilys said in the above answer, you can use singleton class to store data. Before displaying your loading screen check if you single ton object has data or not. If yes then skip displaying your loading screen
I need to write real time log data in an Activity window from a Service to watch what is happening. Like Console.WriteLine.Log.I(), but that isn't good for real time. If I write to a TextView, I need to periodically refresh the Activity and save data in onDestroy() when the screen orientation is changed. It is complex, and I don't now how to refresh the Activity from a static method. What is a simple solution for this?
Maybe a good idea will be writing logs to a certain log file on SD card and then when your Activity is in foreground you just need to load the file contents to your TextView. Hope this helps.
I am creating app that download 4-5 images from server and display as gallery.
It working fine in normal condition. but when there is incoming call or device is in sleep mode my activity load data from starting after onResume, i am not able to load data(Resume activity) from previous state of activity.
Is there any soulution?
Thanks
You should read how to handle runtime changes.
Basically, under some situations your Activity will be recreated. To preserve state you can pass objects between old and new Activity, using onSaveInstanceState() in old activity and onRestoreInstanceState() in new activity.
Check out Saving Cache Files. Save your images on pause and restore them on resume.
You should probably cache the files, so it works like this, check if files already exist, if not download, when files exist load pictures,
http://developer.android.com/guide/topics/data/data-storage.html#ExternalCache