Reputation: 211
I know that the first you gonna this is... why the heck on the world you then use AsyncTask.
So here is my problem i am working on some Android app (API 7 for android 2.1 or higher) , and i am testing on emulator and everything was fine, so then i tested on HTC Sensation and it says NetworkOnMainThreadExeption!
I was downloading some pictures and then draw on the map.
So to solve this problem every (internet connection) in this case downloading the pictures i must put on AsyncTask to work.
So i need a method how to know when all pictures are done so i can start drawing..
I was trying so much and no result i have no idea. I got one solution with handler but if run on slower net i get nullpointer(because the pictures are not downloaded).
So please help me.
EDIT:
here is the idea:
Bitmap bubbleIcon ;
onCreate(){
...
// i am making call for Async
new ImgDown().execute(url);
//and then i calling functions and classes to draw with that picture bubbleIcon !
DrawOnMap(bubbleIcon);
}
//THIS IS ASYNC AND FOR EX. SUPPOSE I NEED TO DOWNLOAD THE PIC FIRST
class ImgDown extends AsyncTask<String, Void, Bitmap> {
private String url;
public ImgDown() {
}
@Override
protected Bitmap doInBackground(String... params) {
url = params[0];
try {
return getBitmapFromURL(url);
} catch (Exception err) {
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
bubbleIcon = result;
bubbleIcon = Bitmap
.createScaledBitmap(bubbleIcon, 70, 70, true);
}
public Bitmap getBitmapFromURL(String src) {
try {
Log.e("src", src);
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
// /tuka decode na slika vo pomalecuk kvalitet!
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
Bitmap myBitmap = BitmapFactory
.decodeStream(new FlushedInputStream(input));
Log.e("Bitmap", "returned");
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
Log.e("getBitmapFromURL", e.getMessage());
return null;
}
}
class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int byteValue = read();
if (byteValue < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
}
i hope now is more clear.
Upvotes: 14
Views: 54844
Reputation: 8598
You can write your own Delegate to delegate info about finishing the task, using OOP principles:
task_delegate.java
public interface TaskDelegate {
void TaskCompletionResult(String result);
}
main_activity.java
public class MainActivity extends Activity implements TaskDelegate {
//call this method when you need
private void startAsynctask() {
myAsyncTask = new MyAsyncTask(this);
myAsyncTask.execute();
}
//your code
@Override
public void TaskCompletionResult(String result) {
GetSomethingByResult(result);
}
}
my_asynctask.java
public class MyAsyncTask extends AsyncTask<Void, Integer, String> {
private TaskDelegate delegate;
protected MyAsyncTask(TaskDelegate delegate) {
this.delegate = delegate;
}
//your code
@Override
protected void onPostExecute(String result) {
delegate.TaskCompletionResult(result);
}
}
Upvotes: 9
Reputation: 356
class OpenWorkTask extends AsyncTask {
@Override
protected Boolean doInBackground(String... params) {
// do something
return true;
}
@Override
protected void onPostExecute(Boolean result) {
// The results of the above method
// Processing the results here
myHandler.sendEmptyMessage(0);
}
}
Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
// calling to this function from other pleaces
// The notice call method of doing things
break;
default:
break;
}
}
};
Upvotes: 32
Reputation: 356
class openWorkTask extends AsyncTask<String, String, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
//do something
return true;
}
@Override
protected void onPostExecute(Boolean result) {
// The results of the above method
// Processing the results here
}
}
Upvotes: 2
Reputation: 4388
I would use a Progress Dialog if I were you. This way users can see that something is happening while the ASyncTask downloads the picture. On PostExecute, call a method from your main code that checks if the pictures are null. Remember you cannot update the UI in the doInBackground method so do any UI work in either onPreExecute or onPostExecute
private class DownloadPictures extends AsyncTask<String, Void, String>
{
ProgressDialog progressDialog;
@Override
protected String doInBackground(String... params)
{
//Download your pictures
return null;
}
@Override
protected void onPostExecute(String result)
{
progressDialog.cancel();
//Call your method that checks if the pictures were downloaded
}
@Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(
YourActivity.this);
progressDialog.setMessage("Downloading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
@Override
protected void onProgressUpdate(Void... values) {
// Do nothing
}
}
Upvotes: 0