【问题标题】:findViewById() in asyncTaskasyncTask 中的 findViewById()
【发布时间】:2013-07-26 06:31:40
【问题描述】:

我想在 AsyncTask 类中使用 findViewById() 方法...我尝试了 onPostExecute() 和 onPreExecute()。但它不起作用

class Proccess extends AsyncTask<String, Void, Void>{

    @Override
    protected Void doInBackground(String... arg0) {
    TextView txt = (TextView) findViewById(R.id.tvResult); // cause error
        return null;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        TextView txt = (TextView) findViewById(R.id.tvResult); // cause error
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        TextView txt = (TextView) findViewById(R.id.tvResult); // cause error

    }
}

【问题讨论】:

  • 为什么要在异步任务中使用 TextView?
  • 用于更改文本 + 我想向 RelativeLayout 添加更多文本视图!

标签: java android asynchronous


【解决方案1】:

像这样编辑你的代码

class Proccess extends AsyncTask<String, Void, Void>{

@Override
protected Void doInBackground(String... arg0) {

    TextView txt = (TextView) findViewById(R.id.tvResult); // cuse error
    return null; //this should be the last statement otherwise cause unreachable code.
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
    TextView txt = (TextView) findViewById(R.id.tvResult); // cuse error
}

@Override
protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    TextView txt = (TextView) findViewById(R.id.tvResult); // cuse error

}
}

您的 Process 类应该是 Your Activity 的内部类否则会导致 findViewById(int) 方法未定义。

【讨论】:

  • 这就是我要说的改变你的代码,就像我更新的代码一样。
  • 并复制粘贴您的 Process 类到您的活动类中。
【解决方案2】:

您可能会将您的视图传递给 AsyncTask 构造函数,正如 Can't access "findViewById" in AsyncTask 中提到的那样,尽管我认为应该只保留一个弱引用,以防在 onPostExecute 被触发时视图不再存在(所以我们不t 使用过时的视图或阻止其垃圾收集):

public class Process extends AsyncTask<String, Void, Void>{
    private WeakReference<TextView> textViewRef;

    public Process(TextView textView) {
        this.textViewRef = new WeakReference<TextView>(textView);
    }

    @Override
    protected Void doInBackground(String... params) {
        // do your stuff in background
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        TextView textView = textViewRef.get();
        if (textView != null) {
            // do something with it
        }
        else {
            // the view has been destroyed
        }
    }
}

现在没有时间检查它,但应该这样做,前提是您的活动/片段将视图传递给异步任务。

哦,顺便说一句:永远不要在 doInBackground 中以任何方式使用视图,因为此方法在后台线程上执行,并且 UI 组件只能从主线程中操作。

【讨论】:

  • 我没有足够的堆栈溢出声誉来评论 Tarun 的帖子,但这绝对是错误的:1/ 'edited' 代码仍然包含对 doInBackground 中 textview 的引用,即 非常* 很糟糕,因为它违反了线程规则(参见developer.android.com/guide/components/… 中的规则#2)。 2/ 我同意 Snicolas 的观点,即直接在异步任务中使用 findViewById 是不好的做法(尤其是在异步任务期间发生屏幕旋转的情况下)。
【解决方案3】:

您应该在 Activity 中获取对 textview 的引用并存储为数据成员。它可以从内部 AsyncTask 访问。

在 postExecute 中使用 findViewById 的缺点是,您的 AsyncTask 可能会在您的活动结束后终止,然后 findViewById 会使您的应用崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    相关资源
    最近更新 更多