francesco bocci
francesco bocci

Reputation: 69

Why View Fragment is null in AsyncTask?

This is my Fragment class:

public class StanzeFragment extends Fragment {

public StanzeFragment(){}

Button vis_stanze;
public TextView testo;

View rootView;

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

    rootView = inflater.inflate(R.layout.activity_log_stanze, container, false);
    testo = (TextView) rootView.findViewById(R.id.testo);

    vis_stanze = (Button)rootView.findViewById(R.id.bottone_stanze);
    vis_stanze.setOnClickListener( new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            getStanze backgroundTask = new getStanze();
            backgroundTask.execute();
        }
    });
    return rootView;
    }

public void setTesto(String value){
    testo.setText(value);
     }
    }

But now i need to call method "setTesto" in other class (AsyncTask class), in onPostExecute method:

    @Override
    protected void onPostExecute(String result) {
      StanzeFragment test = new StanzeFragment();
        test.setTesto(result);
    }

He give me this error:

" java.lang.NullPointerException: Attempt to invoke virtual method 'void com.androidnuovosa.bocci.navdriwerdb.Utente.StanzeFragment.setTesto(java.lang.String)' on a null object reference" .. ..I think because he don't see View of Fragment, how can I resolve this problem? Thnks for answer. (I have this problem for other class too)

EDIT:

AsyncTask isn't in StanzeFragment

Upvotes: 2

Views: 406

Answers (2)

Markus Kauppinen
Markus Kauppinen

Reputation: 3235

Fragments are supposed to be instantiated by the system (as they are defined in the layout XML) or from the code by using the FragmentManager methods.

If you just instantiate a StanzeFragment like that, it does not actually appear on the view stack and its testo TextView is null. This seems to be your problem.

In your case apparently the Fragment is already visible when the AsyncTask runs, you should just get a reference to that Fragment instance instead of creating a new one.

The FragmentManager has methods to find a Fragment either by the id (as defined in the XML) or by the tag (given when showing it programmatically):

findFragmentById()

findFragmentByTag()

EDIT:

In your layout XML for an Activity you probably have a Fragment:

<fragment
    android:name="com.example.MyFragment"
        android:id="@+id/my_fragment"
    ... />

Now depending on the exact configuration of your app (the Activity type actually) you will call either:

getFragmentManager()

...or...

getSupportFragmentManager()

...so, for example:

FragmentManager fm = getFragmentManager();

to access the FragmentManager. And then you find your MyFragment with its id my_fragment:

MyFragment myFrag = (MyFragment)fm.findFragmentById(R.id.my_fragment);

This should all be done in the Activity which contains the said Fragment.

Another (alternative) way to keep references to Fragments would be to implement the onAttachFragment() method in your Activity. (In the Activity which will contain the said Fragment):

@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);

    if (fragment instanceof StanzeFragment) {
        stanzeFragment = (StanzeFragment) fragment;
    }
}

The onAttachFragment() method is ran when your Fragment is constructed and shown by the system. The exact wording in the documentation is

Called when a Fragment is being attached to this activity, immediately after the call to its Fragment.onAttach() method and before Fragment.onCreate().

So at that point the Fragment isn't completely ready yet, but this anyway gets a reference to the correct Fragment instance which actually will appear on the device screen. So when you later in your code use stanzeFragment you can access its TextViews and whatnot.

Upvotes: 2

user1506104
user1506104

Reputation: 7086

If you are executing the AsyncTask inside your StanzeFragment, you just do this:

@Override
protected void onPostExecute(String result) {
    setTesto(result);
}

Upvotes: 0

Related Questions