I am using listview to display data, inside listview i am using image in every listeitem.
I am following this tutorial
http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List4.html
new Handler().post(new Runnable(){
#Override
public void run() {
//Need to subclass to use Asynctask
class DownloadImage extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
Drawable dImage = Util.getImageFromURL(imageURL);
getImageIcon().setImageDrawable(dImage);
return null;
}
}
new DownloadImage().execute();
}
});
this looks good for lazzy loading image, but there is one problem it won't display any image until user touch screen or try to scroll results or any interaction by the user to handset device keys.
If i try to scroll results it dispaly all list item images.... what may go wrong ???
It's hard to say without more context. In particular, where is this code being called from, and what does getImageIcon() do??
One problem I see is that you're setting the image icon in a background thread rather than in the UI thread. This could be the reason why it doesn't seem to change until a ui event triggers a refresh. Try changing DownloadImage to something like the following:
class DownloadImage extends AsyncTask<Void, Void, Drawable>{
#Override
protected Drawable doInBackground(Void... params) {
return Util.getImageFromURL(imageURL);
}
#Override
protected void onPostExecute( Drawable d ) {
getImageIcon().setImageDrawable(d);
}
}
new DownloadImage().execute();
If I'm right, that should fix the problem.
If that does work, great, although I think your code could use a little cleanup. Provided that this is all taking place in the UI thread (which is probably true given that you're instantiating a new Handler in this thread), you shouldn't need to use a Handler at all, nor should you need to create a new Runnable. Just strip those out and create a new DownloadImage instance directly and call execute().
Related
I'm a beginner in Android development. I'm trying to learn multi-threading and working with the internet so I'm doing that by downloading a PDF file from a link through the background thread using AsyncTask. I have confusions about what the best way is to go about it.
Do I create the URI and other necessary connectivity objects in the onCreate or in the doInBackground method of the AsyncTask class?
To download just a single PDF file, what sort of objects do I need to call?
I have checked the documentation but I couldn't really understand it. I'd appreciate a layman's explanation and possibly pseudo-code.
Here is the code I have so far:
public class MainActivity extends AppCompatActivity {
Button downloadPDF;
DownloadingClass downPDF;
private static final String TAG = "omar.asynctaskdemo;";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String urlExample = "https://doc.lagout.org/programmation/Actionscript%20-%20Flash%20-%20Flex%20-%20Air/Flash%20Development%20for%20Android%20Cookbook%20-%20Labrecque%20-%20Packt%20%282011%29/Flash%20Development%20for%20Android%20Cookbook%20-%20Labrecque%20-%20Packt%20%282011%29.pdf");
downloadPDF = findViewById(R.id.download_pdf);
downPDF = new DownloadingClass();
downloadPDF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downPDF.execute();
}
});
}
private class DownloadingClass extends AsyncTask<String, Integer, Void>{
#Override
protected Void doInBackground(String... strings) {
return null;
}
}
}
AsyncTask just runs your code in the background thread. To download a pdf file is like any other file.
You will require to use HttpUrlConnection, Create a FileOutputStream and write the inputstream. Refer this
Have the above code executed in doInBackground of AsyncTask class and better pass the url in the constructor and do everything inside the doInBackground method. Since you don't want to block the UI thread.
private class CreateGridTask extends AsyncTask<Void, Void, Void> {
private CreateGridTask() {
}
protected Void doInBackground(Void... voidArr) {
GridView.this.grid.create(((WordSearchApplication) GridView.this.getContext().getApplicationContext()).getLexicon());
return null;
}
protected void onPostExecute(Void voidR) {
GridView.this.startTime.setToNow();
GridView.this.onGridReadyListener.onGridReady();
GridView.this.invalidate();
}
}
public interface OnGridReadyListener {
void onGridReady();
}
public interface OnWordFoundListener {
void onWordFound(Word word, int i);
}
Android Studio GridView error getting while doInBackground with AsyncTask method, where i done wrong in code pls and this
You should not create the grid this way.
Instead, you should implement BaseAdapter. If cells have a number of particularly heavy operations, you may use AsyncTask within the adapter. Keep in mind, AsynTask starts a thread that is not attached to the UIThread and should not manipulate the UI until onPostExecute is called (Even then, use caution. Especially with a GridView where views may have been recycled)
Hello i am new to android and android thread so want to know that
How could we use more number of thread in order to perform every single task or method so that while user click on any UI component it does effect the performance ,having little knowledge of how the handler thread and asynctask work.But how can we run every method inside the asynctask so to do the operation and mean while user can do the other operation also.
In the application
i have voice recording from mic.
next showing progress bar.
next showing gallery with some image and with that setting effect to the picture.
The recommended way is to use AsyncTasks for long running tasks. So, not everything needs to be run with AsyncTasks, as you can get a performance hit due to the context switching.
As for how AsyncTasks work, read the documentation.
Use an AsyncTask and make sure to implement these as needed. You mention the idea of doing something in the background while a user is doing something so I'm guessing you'll want to alter the UI.
Take a look at these links for an more details from Android. They cover Runnable, AsyncTask and Handler
Overview of them all http://developer.android.com/guide/components/processes-and-threads.html
AsyncTask example http://developer.android.com/reference/android/os/AsyncTask.html
Old but relevant, Painless Threading http://android-developers.blogspot.com/2009/05/painless-threading.html
Another, more complex example http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
I don't generally paste full examples in here but I had a lot of trouble finding an example I was happy with for a long time and to help you and others, here is my preferred method. I generally use an AsyncTask with a callback to the Activity that started the task.
In this example, I'm pretending that a user has triggered onClick(...) such as with a button, but could be anything that triggers a call into the Activity.
// Within your Activity, call a custom AsyncTask such as MyTask
public class MyActivity extends Activity implements View.OnClickListener, MyTask.OnTaskComplete {
//...
public void onClick(View v) {
// For example, thet user clicked a button
// get data via your task
// using `this` will tell the MyTask object to use this Activty
// for the listener
MyTask task = new MyTask(this);
task.execute(); // data returned in callback below
}
public void onTaskComplete(MyObject obj) {
// After the AsyncTask completes, it calls this callback.
// use your data here
mTextBox.setText(obj.getName);
}
}
Getting the data out of a task can be done many ways, but I prefer an interface such as OnTaskComplete that is implemented above and triggered below.
The main idea here is that I often want to keep away from inner classes as they become more complex. Mostly a personal preference, but it allows me to separate reusable tasks outside of one class.
public class MyTask extends AsyncTask<Void, Void, MyObject> {
public static interface OnTaskComplete {
public abstract void onTaskComplete(MyObject obj);
}
static final String TAG = "MyTask";
private OnTaskComplete mListener;
public MyTask(OnTaskComplete listener) {
Log.d(TAG, "new MyTask");
if (listener == null)
throw new NullPointerException("Listener may not be null");
this.mListener = listener;
}
#Override
protected MyObject doInBackground(Void... unused) {
Log.d(TAG, "doInBackground");
// do background tasks
MyObbject obj = new MyObject();
// Do long running tasks here to not block the UI
obj.populateData();
return
}
#Override
protected void onPostExecute(MyObject obj) {
Log.d(TAG, "onPostExecute");
this.mListener.onTaskComplete(obj);
}
}
I've used the AsyncTask example from vogella website, I've created a class file with it.
I'm calling it from Activity A to update the postalcode's TextView, it's working.
I'm wondering how can I call the same AsyncTask from Activity B to update another postal code TextView.
So one AsyncTask, 2 calls from different Activities to update different TextViews.
I've to do something onPostExecute(), right?
Some example code, is much appreciated.
Thanks in advance
You can (I guess) pass the TextView to the AsyncTask when you instantiate it.
All without the IDE open so apologies if the syntax is off...
public class ExampleTask extends AsyncTask<Void, Void, Void> {
private TextView targetTextView;
public ExampleTask(TextView target) {
targetTextView = target;
}
#Override
protected String doInBackground(Void... orSomething) {
//do work and get a value I guess
}
#Override
protected void onPostExecute(String result) {
targetTextView.setText(result);
}
}
Then you'd call this:
ExampleTask task = new ExampleTask(theTextViewToUpdate);
task.execute();
You'd want to be careful about the scope of the task objects you instantiate as that reference to a TextView could end up leaking memory from your activities.
Here I am not good, but you can try
It is possible to reuse AsyncTask for different Activities.
For this you must take different parameter from different Activities.
In AsyncTask Class initiate a constructor with a case parameter (which is described in other activities) which will decide ,it is called by Activity A or B or C.
Now use switch case statement and move ahead.
I have two AsyncTasks as inner classes in my Activity. One returns an ArrayList in doInBackground and asigns a ListAdapter to it on postExecute. The other AsyncTask returns a StringArray and sets some TextViews.
On Rotation everything is gone, also the layout changes on Rotation.
I'd like to have access to the results of the doInBackground-Methods. If I had access I could just simply save the variables in onSaveInstanceState and reasign the values manually.
You can access the results of doInBackground in onPostExecute.
Simply change your class to:
public class YourTask extends AsyncTask<Void, Void, ObjectYouWantToReturn> {
#Override
protected ObjectYouWantToReturn doInBackground(Beneficiary... params) {
ObjectYouWantToReturn obj = new ObjectYouWantToReturn();
//... do your stuff
return obj;
}
#Override
protected void onPostExecute(ObjectYouWantToReturn result) {
//there you go, here you have the results from doInBackground
}
}
Shared preferences is solution of your problem i think.
revise the link given below.
http://developer.android.com/guide/topics/data/data-storage.html#pref
http://thedevelopersinfo.com/2009/11/25/getting-sharedpreferences-from-other-application-in-android/