Can't Access "Findviewbyid" in Asynctask

Can't access findViewById in AsyncTask

Pass your inflated view to the AsyncTask like this :

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);
}

Then call like so,

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

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

Can not access “findViewById” in AsyncTask

Just pass the Activity as a parameter to the AsyncTask class. See here. Note that its bad practice to store context as a member variable since the context may change.

findViewById() in asyncTask

Edit your code like this

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

}
}

And your Process class should be innerclass of Your Activity. other wise it cause method findViewById(int) is undefined.

Passing view to AsyncTask to access findViewById

I really did not like the idea of passing context, and the View around to different objects, and like to keep the view specific functionality within the activity class itself, so I implemented an interface, that I passed around, as follow:

Here is my interface:

public interface IProfiler {
void ShowProgressbar();
void HideProgressbar();
void MakeToast();
}

My activity class implements this interface, as follow:

public class ProfileActivity extends MenuActivity implements IProfiler {

private ProgressBar mProgressar;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ActivityProfileBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_profile);
binding.setUser(new User());
binding.setViewActions(new ProfileViewModel(this));

//get the toolbar
Toolbar tb = (Toolbar)findViewById(R.id.toolbarMain);
setSupportActionBar(tb);

//set the Progressbar
mProgressar = (ProgressBar)findViewById(R.id.progressPostUser);
}

@Override
public void ShowProgressbar() {
mProgressar.setVisibility(View.VISIBLE);
}

@Override
public void HideProgressbar() {
mProgressar.setVisibility(View.GONE);
}

@Override
public void MakeToast() {
Toast.makeText(this, "Some toast", Toast.LENGTH_SHORT);
}
}

My ProfileViewModel, which excepts the interface as parameter:

    public class ProfileViewModel {

private User mUser;
private IProfiler mProfiler;

public ProfileViewModel(IProfiler profiler){
mProfiler = profiler;
}

public void onSaveClicked(User user) {
try {
String nameTest = user.get_name();
String surnameTest = user.get_surname();

new AsyncTaskPost(mProfiler).execute(new URL("http://www.Trackme.com"));
}
catch (Exception ex) {

}
}
}

And then finally, my AsyncTaskPost.

public class AsyncTaskPost extends AsyncTask<URL, Void, Void> {

private IProfiler mProfilerActions;

public AsyncTaskPost(IProfiler profilerActions){
mProfilerActions = profilerActions;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
mProfilerActions.ShowProgressbar();
}

@Override
protected Void doInBackground(URL... urls) {
try{
Thread.sleep(5000);
return null;
}
catch (Exception ex) {
return null;
}
}

@Override
protected void onPostExecute(Void aVoid) {
mProfilerActions.HideProgressbar();
mProfilerActions.MakeToast();
}

@Override
protected void onCancelled() {

super.onCancelled();
mProfilerActions.HideProgressbar();
}
}

can't findViewById inside AsyncTask

onCreate called before onCreateView

more info on Android Developer Site

in your scenario you create your adapter in onCreate method but you initilize your view in onCreateView, so you get NPE, because rootView is null in adapter class

you call following code in onCreate method:

ListAdapter listAdapter = new Adapter_ConversationFragmentAdapter(getActivity(), R.layout.items_conversation,myFragmentView);
setListAdapter(listAdapter);

myFragmentView being initialized in onCreateView, so this is null in onCreate method, so you can use following code:

copy following code to onCreate method:

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

or move adapter initializing after that line

UPDATE

change your code to:

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

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

ListAdapter listAdapter = new Adapter_ConversationFragmentAdapter(getActivity(), R.layout.items_conversation,myFragmentView);
setListAdapter(listAdapter);

return myFragmentView;
}

and remove onCreate part

can't findViewById inside AsyncTask

onCreate called before onCreateView

more info on Android Developer Site

in your scenario you create your adapter in onCreate method but you initilize your view in onCreateView, so you get NPE, because rootView is null in adapter class

you call following code in onCreate method:

ListAdapter listAdapter = new Adapter_ConversationFragmentAdapter(getActivity(), R.layout.items_conversation,myFragmentView);
setListAdapter(listAdapter);

myFragmentView being initialized in onCreateView, so this is null in onCreate method, so you can use following code:

copy following code to onCreate method:

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

or move adapter initializing after that line

UPDATE

change your code to:

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

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

ListAdapter listAdapter = new Adapter_ConversationFragmentAdapter(getActivity(), R.layout.items_conversation,myFragmentView);
setListAdapter(listAdapter);

return myFragmentView;
}

and remove onCreate part

Android: cannot resolve method 'findViewById(int)' in AsyncTask

findViewById is a method of Activity class.

And you have

 public class ImageDownloader
extends AsyncTask<String, Integer, Bitmap> // not a activity class

If you need the data back in activity you could use interface as a callback to the activity.

I would update ui in Activity itself. look @ blackbelts answer

How do I return a boolean from AsyncTask?

Or

Make AsyncTask an inner class of Activity class and update ui in onPostExecute

Also you might find this blog by Alex Loockwood interesting

http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html



Related Topics



Leave a reply



Submit