无法在AsyncTask中访问“findViewById”

时间:2013-01-04 20:05:57

标签: android android-asynctask

我正在使用AsyncTask类从php文件下载数据。下载后,我想把这些数据放到不同的TextViews中,但我不能使用findViewById方法。

问题在于,我是通过单独的类来完成的,而且它都在一个片段中。

这是我的代码:

public class RecuperarComentarisFoto extends AsyncTask<String, String, String>{
private Context mContext;
[...]
public RecuperarComentarisFoto(Context context){
    this.mContext=context;
}
@Override
protected void onPreExecute() {
    [...]
}

@Override
protected String doInBackground(String... arg0) { 
    params.add(new BasicNameValuePair("pid", "1"));
    JSONObject json = jsonParser.makeHttpRequest(url_get_comentaris, "GET", params);
    JSONArray productObj;
    //HERE I RETRIEVE DATA FROM JSON. ITS WORKING OK.

    return null;
}

我遇到问题的地方:

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    this.pDialog.dismiss();
    TextView comentariEditText = (TextView) findViewById(R.id.commentsMostrar);
}

我试过这个:

        TextView comentariEditText = (TextView) mContext.findViewById(R.id.commentsMostrar);

但是也不行。

请注意,我正在从Fragment中调用此AsyncTask。如您所见,我必须将getActivity()检索到的上下文传递给AsyncTask:

public class MyFragmentA extends Fragment {
Context cont;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);

    cont=getActivity();
    new RecuperarComentarisFoto(cont).execute();
    return myFragmentView;
}


}

我该怎么办?

谢谢。

7 个答案:

答案 0 :(得分:26)

将您的虚增视图传递给AsyncTask,如下所示:

public class RecuperarComentarisFoto extends AsyncTask<String, String, String>{
private Context mContext;
private View rootView;
[...]
public RecuperarComentarisFoto(Context context, View rootView){
    this.mContext=context;
    this.rootView=rootView;
}
@Override
protected void onPreExecute() {
    [...]
}

@Override
protected String doInBackground(String... arg0) { 
    params.add(new BasicNameValuePair("pid", "1"));
    JSONObject json = jsonParser.makeHttpRequest(url_get_comentaris, "GET", params);
    JSONArray productObj;
    //HERE I RETRIEVE DATA FROM JSON. ITS WORKING OK.

    return null;
}
@Override
protected void onPostExecute(String result) {
    //super.onPostExecute(result);  <--GET RID OF THIS (it will screw up on 2.1 devices)
    this.pDialog.dismiss();
    // use rootview to findViewById
    TextView comentariEditText = (TextView) rootView.findViewById(R.id.commentsMostrar);
}

然后这样打电话,

View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);

cont=getActivity();
new RecuperarComentarisFoto(cont, myFragmentView).execute();

答案 1 :(得分:1)

在传递MyFragmentA上下文而不是getActivity()后尝试:

 cont=this;
 new RecuperarComentarisFoto(cont).execute();

并将RecuperarComentarisFoto更改为

public class RecuperarComentarisFoto extends AsyncTask<String, String, String>{
public Fragment mContext;
[...]
public RecuperarComentarisFoto(Fragment context){
    this.mContext=context;
}
@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    this.pDialog.dismiss();
    TextView comentariEditText = 
                    (TextView)mContext.findViewById(R.id.commentsMostrar);
}
//...your code..

答案 2 :(得分:1)

只需使用视图myFragmentView向AsyncTask添加一个额外的参数,然后在其上找到您的textview。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);

    cont=getActivity();
    new RecuperarComentarisFoto(cont, myFragmentView).execute();
    return myFragmentView;
}

然后只使用该视图..

TextView comentariEditText = (TextView) mView.findViewById(R.id.commentsMostrar);

答案 3 :(得分:1)

使您的AsyncTask独立于活动

如果

  • 您的AsyncTask是一个单独的Java类(活动之外) 而且您仍然想访问来自任何Activity的View元素 AsyncTask
  • 您想将AsyncTask与其他一些活动重复使用,而无需 您的AsyncTask
  • 中的任何代码更改

答案 。使用界面

  

优势?
  接口使事物独立(松散耦合)

您可以按照以下步骤操作:

1)创建一个界面

public interface AsyncTaskListener{

   public void giveProgress(int progress);

}

2)在AsyncTask中使用侦听器

 DownloadSongTask extends AsyncTask<String,Integer,Void>{

    private AsyncTaskListener listener;

    public DownloadSongTask(Context context)
    {
        listener= (AsyncTaskListener)context;    // Typecast 
    }

    @Override
    public void doInbackGround(String... params)
    {
         // Download code
         int downloadPerc = // calculate that
         publish(downloadPerc);   
    }

    @Override
    public void onProgressUpdate(Integer... params)
    {
         listener.giveProgress(params[0]);  // Use it 
    }

}

3)在“活动和覆盖”方法中实现界面

 public class YourActivity extends AppcompatActivity implements AsyncTaskListener{

    private TextView textView;

    // Activity code //
    new  DownloadSongTask(this).execute("Paradise.mp3");  // this is how you start Task

    @Override 
    public void giveProgress(int progress){
       textView.setText(progress+"");      
    }

}

未来

在必须在其他一些Activity中使用Your AsyncTask之前,您将不会意识到代码的美妙之处。
可以说,将来您想在其他活动中使用此AsyncTask,以显示微调器的进度。
您将如何使用它? 简单!实现该接口并覆盖该方法。

public class YourActivity extends AppcompatActivity implements AsyncTaskListener{

     private Spinner spinner;

     // Activity code //
     new  DownloadSongTask(this).execute("Paradise.mp3");  // this is how you start Task

    @Override 
    public void giveProgress(int progress){
       // Your Spinner code       
    }

}

答案 4 :(得分:0)

您可以将myFragmentView设为全局,这样您甚至可以通过onStart()等片段方法从任何地方访问您的观看次数。

答案 5 :(得分:0)

试试这个((Activity)context)它对我有用......

TextView comentariEditText = 
(TextView) ((Activity)context).findViewById(R.id.commentsMostrar);

答案 6 :(得分:0)

使用RecuperarComentarisFoto(Context context, View rootView)接受的答案给了我以下信息:

java\MyFragmentA.java:64: error: constructor RecuperarComentarisFoto in class RecuperarComentarisFoto cannot be applied to given types;
                new RecuperarComentarisFoto(cont, myFragmentView).execute();
                ^
  required: no arguments
  found: MyFragmentA,View
  reason: actual and formal argument lists differ in length

我不知道为什么结果与上面的建议不同。我使用的是API版本24。

因此,我在initialize()内使用了另一种方法AsyncTask

public class RecuperarComentarisFoto extends AsyncTask<String, String, String>{
    private Context mContext;
    private View rootView;
    ...
    public initialize(Context context, View rootView){
        this.mContext=context;
        this.rootView=rootView;
    }
    ...
}

在调用MyFragmentA类的内部:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ...
        View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
        cont=getActivity();

        RecuperarComentarisFoto rcf = new RecuperarComentarisFoto();
        rcf.initialize(cont, myFragmentViewt);
        rcf.execute(this);
        ...
    }