在Activity类中编写AsyncTask类是否可以?或者我应该为此创建另一个文件?但是,在这种情况下,我无法操纵UI,或从AsyncTask更新它。那么,如果我要为AsyncTask创建另一个文件,那我怎么能更新Activity类中的UI呢?提前致谢!
答案 0 :(得分:2)
在Activity类中编写AsyncTask类是否可以?
是的,没关系,但不是一个好习惯。这是一个干净的编码问题,将视图与控制器分开。它还可能导致内存泄漏问题。您可以将Activity的引用传递给AsyncTask,但应该只是一个弱引用。
我无法操作UI,或者从AsyncTask更新它。所以,如果我是 为AsyncTask创建另一个文件,然后我如何更新UI 活动课?
在这种情况下,有很多方法可以更新UI。您可以使用BroadcastReceiver
,Handler
或Interface
。
我建议您使用Interface
,因为它是最简单的,我认为是最合适的。{/ p>
以下是一个示例:
您为AsyncTask创建一个新文件。你编写了一个新的子类AsyncTask。
public class DownloadTask extends AsyncTask<String, Float, Long>
{
public DownloadTaskListener mListener;
public interface DownloadTaskListener
{
public void onDownloadFinish();
public void onDownloadProgress(float progress);
}
@Override
protected Long doInBackground(String... arg0)
{
//start downloading
return 0L; //return download size
}
protected void onProgressUpdate(Float... progress)
{
if(mListener != null)
{
mListener.onDownloadProgress(progress[0]);
}
}
protected void onPostExecute(Long result)
{
if(mListener != null)
{
mListener.onDownloadFinish();
}
}
}
正如您在此处所见,您可以使用界面的这些方法来通知UI的更新。
public interface DownloadTaskListener
{
public void onDownloadFinish();
public void onDownloadProgress(float progress);
}
在您的MainActivity中,您必须实现该接口,以便回调起作用:
public class MainActivity extends Activity implements DownloadTaskListener
{
DownloadTask download = new DownloadTask();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
download.mListener = this;
download.execute("Download URL");
}
@Override
public void onDownloadFinish()
{
MainActivity.this.runOnUiThread(new Runnable()
{
public void run()
{
//updates to UI here.
}
});
}
@Override
public void onDownloadProgress(float progress)
{
MainActivity.this.runOnUiThread(new Runnable()
{
public void run()
{
//updates to UI here.
}
});
}
}
看看这一行:
download.mListener = this;
您只需传递Activity的引用(实现接口),以便AsyncTask可以调用Activity的接口方法,以便您更新Activity。
还要注意AsyncTask是一个Thread。更新UI的某些更改时,应始终在主线程或UI线程中执行此更改。检查这部分:
MainActivity.this.runOnUiThread(new Runnable()
{
public void run()
{
}
});
对不起,不是专业的解释员,但我希望我能为你清楚说明。 :)
答案 1 :(得分:0)
是的,没关系,但在我的情况下,我使用另一个文件。
在onPostExecute方法中,您可以使用UI进行intercat:
您可以将活动/片段传递给AsyncTask,并在onPostExecute中更新您的&#39; UI。
您可以使用界面(回调)来获得结果 - Android - Jsoup: How to get RESULT from Jsoup.connect("url").get() from AsyncTask
我更喜欢第二个选项
答案 2 :(得分:0)
你可以这样做。如果将AsyncTask Class
放在“活动本身”中,则不会出现问题。
我更喜欢将我的AsyncTask
类保存在不同的文件中,而且我与UI交互的方式如下:
onPostExecute
我认为这是一种更清晰的做事方式。如果你使用 EventBus 一次,你会爱上它。
答案 3 :(得分:0)
一般来说,这不好,因为在软件开发中
人们应该尽量避免耦合。
现在考虑Android框架,imho,UI是UI和背景
流程,服务是另一回事。
就个人而言,我不使用这种方法,因为我不喜欢耦合,加上单元测试将是一个痛苦的屁股。但是,如果有人决定采用这种方法,那么应该考虑一下它究竟是什么:
Q1:你想要哪一堂课?
内部类或静态嵌套类?
- 内部课程 - 对于内部类,因为类是其封闭类的成员,所以可以访问封闭实例的变量和成员。这里的问题可能是在轮换期间(Activity),活动中的一些变量可能会发生变化。
- 静态嵌套类 - 静态嵌套类的行为类似于外部类,因此无法访问其封闭的类成员和变量。它可以使用的唯一方法是通过对象引用。这种方法基本上告诉你,另一个类和静态嵌套类之间没有区别。
编辑 - 轮换的一些起点
由于上述条件以及Android应该真正处理旋转的事实,我使用以下概念:
//changed from activity to fragment if rotation is considered.
public CustomFragment extends Fragment{
@Override
void onCreate(Bundle saveInstance){
super.onCreate(saveInstance);
//for avoiding rotation problems
setRetainInstance(true);
new CustomAsyncTask(this, callback).execute();
}
public Callback callback = new Callback{
@Override
public void onSuccess(){
//do something
}
@Override
public void onFail(){
//do something
}
@Override
public void onTaskStarted(){
//start showing the progress dialog
}
@Override
public void onTaskInProgress(Integer value){
//progress dialog has some method set progress, check it out
}
}
public interface Callback {
void onSuccess();
void onFail();
void onTaskStarted();
void onTaskInProgress(Integer progress);
}
}
//asynctask class
public class CustomAsyncTask extends AsyncTask<Void, Void, Void> {
private CustomFragment callback;
public AsyncCallerTickets(CustomFragment _callback){
this.callback = _callback;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
callback.onTaskStarted();
}
@Override
@Override
protected void onProgressUpdate(Integer...progress) {
callback.onTaskInProgress(progress[0]);
}
protected Void doInBackground(Void... params) {
//long process
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//dialog.dismiss();?
if(result!=null){
callback.onSucces();
}
else{
callback.onFail();
}
}
}
通过尽可能地分离事物,可以缓解Android中的旋转疼痛。