开发者

If AsyncTask is not an inner class... - some questions

开发者 https://www.devze.com 2023-03-30 19:56 出处:网络
1) I don\'t underestand why the samples of Android almost use AsyncTasks as private inner classes. I know it is convenient to make it inner class but it makes our cl开发者_高级运维ass file longer and

1) I don't underestand why the samples of Android almost use AsyncTasks as private inner classes. I know it is convenient to make it inner class but it makes our cl开发者_高级运维ass file longer and hard to read. ShelvesActivity of Shelves sample application have even 845 lines. Don't you think it is a bad design or bad construction?

2) If I make my ScanStorageTask external class, what do I have to pass to it? entire Activity or only used widgets?

Example: If I must use a WebView, a Button and a ProgressBar in ScanStorageTask. I use this:

ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it.

or this:

ScanStorageTask task = new ScanStorageTask(webView, button, progressBar);


There's nothing wrong with doing it externally, and it actually might be a better design. Passing UI elements around is the kind of tight coupling that can get you into trouble when you have a really large code base anyway.

Why not do it externally and use the "listener" pattern that the UI controls employ? Make your ScanStorageTask its own class, create an OnCompleteListener interface with an onComplete method, and pass that to your ScanStorageTask instance (expose a setOnCompleteListener method or something to that effect). Then, onPostExecute can just do this:

if(onCompleteListener != null)
  onCompleteListener.onComplete(data);

That way, you define your UI updates inside your activity based on the data. It's better separation of concerns and will keep your lines of code per class down, as that seems to be what you'd prefer. If you don't already have this, make a class that represents the data you need to pass in and get out, and that's what you pass in to the task as a param to the execute method and what onPostExecute passes to onComplete.


Inner classes allow you to manipulate the UI of an outer Activity inside onPreExecute(), onPostExecute() and onProgressUpdate() without passing the whole UI structure(s) to the AsyncTask. You are just able to use the activites functions for that.

This is useful since manipulating the UI isn't the main purpose of an AsyncTask. It's doing non-UI background work. And for that, what you usually have to pass is some arguments to do this job (e.g. supplying a URL to download a file).

When you declare your AsyncTask external, you basically can't access your UIs resources inside onPreExecute() (no arguments are passed to this at all), and very hard inside the other two UI functions.

I'd say AsyncTask is just made for beeing used as an inner class to do work and update the UI-thread. See the description:

AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

(from the class documentation)


I had the same problem in may application. I wanted to establish a communitation with a PC using a Socket and I wanted my code to be reusable from several Activities/Fragments.

In the first place I tried not to use an inner class but it is very convenient when you have to update the UI so I found an alternative solution :
I created an outer AsyncTask class wich in charge to communicate with the pc and I created inner classes in each of my activites/fragments with only an override of the onPostExecute() method. this way I can reuse my code AND update the UI.

If you just want to get the result of the task and if responsiveness is not essential for your application, you can use the get() method of the AsyncTask class.


  1. Personally I belive that if you use class only at one point, then it's most readable to also define it there - hence the anon inner class.

  2. It does not matter. From design perspective I'd only pass data that is actually needed. However you need to be aware on one possible pitfall - when activity instance gets deactivated (hidden or orientation changed) and your background thread still runs and tries to show some changes, then you can get various errors or nothing s shown at all.

0

精彩评论

暂无评论...
验证码 换一张
取 消