[英]Can't access “findViewById” in 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;
}
}
我應該怎么辦?
謝謝你。
像這樣將膨脹的視圖傳遞給 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();
試試這個((Activity)context)
它對我有用......
TextView comentariEditText =
(TextView) ((Activity)context).findViewById(R.id.commentsMostrar);
如果
AsyncTask
是一個單獨的 Java 類(在 Activity 之外) ,您仍然希望從AsyncTask
訪問任何Activity
的 View 元素。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)在Activity和Override方法中實現接口
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+"");
}
}
除非您必須在其他活動中使用 Your AsyncTask,否則您不會意識到代碼的美妙之處。
假設將來您想在一些顯示 Spinner 進度的其他活動中使用此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
}
}
在傳遞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..
只需使用視圖 myFragmentView 向您的 AsyncTask 添加一個額外的參數,然后在其上找到您的文本視圖。
@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);
您可以將myFragmentView
全局,這樣您就可以從任何地方訪問您的視圖,甚至可以從onStart()
等片段方法訪問您的視圖。
使用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。
因此我在AsyncTask
使用了一個額外的方法initialize()
:
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);
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.