1

I have an app which load ads from two networks and sets a flash file to webview when started.This is making it too slow on startup, forums told me to use asynctask.Can some one make this code an asynctask.

        public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    airpush=new Airpush(getApplicationContext());
    airpush.startPushNotification(false);
    airpush.startIconAd();
    airpush.startDialogAd();
    airpush.startAppWall();

    mWebView = (WebView) findViewById(R.id.webview);

    mWebView.getSettings().setJavaScriptEnabled(true);

    mWebView.getSettings().setPluginsEnabled(true);

    mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY); 

    mWebView.setBackgroundColor(Color.parseColor("#000000"));

    mWebView.loadUrl("file:///android_asset/game.swf");

    AdView adView = (AdView)this.findViewById(R.id.adView);
    adView.loadAd(new AdRequest());
A.Jouni
  • 377
  • 2
  • 4
  • 14

2 Answers2

4

It will be much more helpful for you to spend a little bit of time understanding the architecture of an AsyncTask than for someone to simply make one for you.

An AsyncTask is actually a fairly simple class to extend and use. An AsyncTask can, in its simplest form, be code that runs in the background (off the UI thread -- this is what causes lockup), but is set up to allow for some code to run in the background, some code to execute before/after, and some code to execute as a progress update if necessary.

You will need to create your own class that extends AsyncTask as shown below. Your task will take three parameters. The first will get passed into the doInBackground function that runs in the background, the second is a type for a parameter that can be passed into a progress update function, and the third is a type to be passed into your onPostExecute fn that runs on the UI thread after the background function has completed. In the simple example below I will not include types to be passed to a post execute function or a progress update function, so they will be of type Void.

 private class YourTask extends AsyncTask<byte[], Void, Void> {

     protected Long doInBackground(byte[]... data) {
         //get the array
         byte[] array = data[0];

         //do something with it.
         HERE IS WHERE YOU RUN YOUR CODE IN THE BACKGROUND THAT IS TAKING TOO LONG ON THE UI THREAD

         //return null because this type needs to match the last type for returning to the postexec fn
         return null;
     }

 }

When you want to run your task you call the following:

new YourTask().execute(someByteArray);

So oftentimes you can stick the code that is taking a long time into that doInBackground function, but you have to be careful because it is off the UI thread and some code does have to be run on the UI thread.

I would recommend doing some profiling to see what code specifically is choking up your UI thread, and run THAT in the background using an AsyncTask. You can do that by using DDMS in Eclipse and use method profiling. Another way would be to use the Debug class and call Debug.startMethodTracing("tracefilename"); when you want to start and Debug.stopMethodTracing();. You can read more about that here. However, your code does load a url (mWebView.loadUrl) so I would assume this may be a big bottleneck!

Just as an addendum, if you want a more in depth example of an AsyncTask, here is one I C&Pd from this useful documentation:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

The above example has code to both exemplify updating progress on the UI during the background task as well as passing a parameter that is then used by the UI thread-running post execute fn.

Daniel Smith
  • 8,561
  • 3
  • 35
  • 58
  • thnx for ur help ,but I don't know much in programming I am 18 ! I learned from the internet – A.Jouni Mar 16 '13 at 23:45
  • that is totally cool! just keep using the internet. Especially the android docs. The biggest thing is just to read a lot, and make real solid attempts at solutions before asking, and *never* ask people to write code for you :) AsyncTasks can be pretty tricky for newbies too because they contain some nuanced thread-related ideas, but i guess thats what you get for trying to optimize! As Don Knuth said: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil" – Daniel Smith Mar 16 '13 at 23:50
  • for what is the array used here ? can I keep it like this ? – A.Jouni Mar 16 '13 at 23:59
  • what array? If it is the byte[] you can ignore that and replace with whatever Type you need – Daniel Smith Mar 17 '13 at 00:03
  • we can continue discussing in chat here: http://chat.stackoverflow.com/rooms/26311/using-asynctask-to-speed-up-android-app-launch-time-chat – Daniel Smith Mar 17 '13 at 00:13
2

I can't just make your code an AsyncTask but I can give you an example and some help. This is an example of AsyncTask

public class TalkToServer extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected void onProgressUpdate(String... values) {
    super.onProgressUpdate(values);

}

@Override
protected String doInBackground(String... params) {
//do your work here
    return something;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
       // do something with data here-display it or send to mainactivity

}

All of your network stuff you will put in doInBackground() then if you need to update the UI you did that in the other methods. After finishing the network stuff you can update UI in onPostExecute().

This is how you would call the task

TalkToServer myAsync = new TalkToServer() //can add params if you have a constructor
myAsync.execute() //can pass params here for `doInBackground()` method

If it is an inner class of your MainActivity then it will have access to member variables of MainActivity. If its a separate class then you can pass context to constructor like

TalkToServer myAsync = new TalkToServer(this);

and create a constructor to accept Context and any other params you want

I strongly suggest going through the docs below and make sure you understand how it works. Maybe the biggest thing to understand when getting started is that doInBackground() doesn't run on the UI so you don't want to try and update any Views here but in the other AsyncTask methods or by passing data back to the MainActivity and update there AsyncTask

codeMagic
  • 44,549
  • 13
  • 77
  • 93
  • If I just need airpush services to be done in background what should I do ? I am a beginner tolerate me :( – A.Jouni Mar 16 '13 at 23:52
  • I'm not familiar with airpush but if it requires network connectivity then you can just do that in the `doInBackground()`. If you want it to return results for `UI` or any other reason then you just pass these results to `onPostExecute()` and you don't need the other methods of `AsyncTask`. I can tolerate you as long as you are trying and not just looking for someone to write your code. We all had to start somewhere so don't worry about it :) – codeMagic Mar 17 '13 at 00:09
  • In "return something" , what should I put instead of something ? – A.Jouni Mar 17 '13 at 00:12
  • Ummm...whatever data you are having sent back through the network. I don't know exactly what you're doing so I don't know what you will get but if you need to get data from a server then you will send it from `doInBackground()` to `onPostExecute()` and do whatever you want there. If it isn't returning anything then you just do your network operations on `doInBackground()` and don't worry about the rest – codeMagic Mar 17 '13 at 00:14
  • Can I return null ? because it requiring to have return since when removed "doInBackground" get underlined in red ! – A.Jouni Mar 17 '13 at 00:41
  • Yes, it can `return null`. If you aren't passing or returning `params` you can change the `AsyncTask` class to `TalkToServer extends AsyncTask`. What I gave was an example but it can be tailored to your needs – codeMagic Mar 17 '13 at 00:46