简体   繁体   中英

nullPointer exception when trying to access adapter after asynctask refresh

I was following along with some videos on making a weather app and somehow ended up trying to launch my AsyncTask from a button pressed in a drop down from my actionbar. Right now the asynctask is a separate class and the application loads the aynctask fine the first time but when i try to refresh and re launch the async task from a button in my actionbar menu the app crashes with a NullPointerException :

07-18 00:45:05.615    5849-5849/johnpark.sunshine E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
            at johnpark.sunshine.MainActivityFragment.processFinish(MainActivityFragment.java:70)
            at johnpark.sunshine.ForeCastLoader.onPostExecute(ForeCastLoader.java:39)
            at johnpark.sunshine.ForeCastLoader.onPostExecute(ForeCastLoader.java:23)
            at android.os.AsyncTask.finish(AsyncTask.java:631)
            at android.os.AsyncTask.access$600(AsyncTask.java:177)
            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4745)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

Its getting a nullPointer exception when trying to access the adapter again. Essentially there is a refresh button in my drop down in my Main activity that extends ActionBar. When i click that button it calls a method from the MainActivityFragment class that calls the execute method of the ForeCastLoader asynctask . In the onPostExecute() method the results are passed back to the fragment through a processFinish() method. Back in that method in ActivityFragment, when trying to use the adapter i get a null pointer exception. Any ideas as to what im doing wrong?

MainActivity

public class MainActivity extends ActionBarActivity
                implements OnNavigationListener, android.support.v7.app.ActionBar.OnNavigationListener {

private final String TAG = this.getClass().getSimpleName();
private boolean mNaviFirstHit = true;
MainActivityFragment mfa;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String[] dropdownValues = getResources().getStringArray(R.array.nav_list);

    android.support.v7.app.ActionBar actionBar = getSupportActionBar();

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(actionBar.getThemedContext(),
            android.R.layout.simple_spinner_item, android.R.id.text1,
            dropdownValues);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setNavigationMode(NAVIGATION_MODE_LIST);
    actionBar.setListNavigationCallbacks(adapter, this);
}

@Override
public boolean onNavigationItemSelected(int position, long id) {
    if (mNaviFirstHit) {
        mNaviFirstHit = false;
        return true;
    }

    if(position==1)
    {
        Intent in = new Intent(getApplicationContext(),SettingsActivity.class);
        startActivity(in);
    }
    if(position==2)
    {
        mfa = new MainActivityFragment();
        mfa.update();
    }
    return true;
}
}

MainActivityFragment

public class MainActivityFragment extends Fragment implements AsyncResponse{

private ArrayList <String> list = new ArrayList<>();
static ListView lv;
ForeCastLoader  f = new ForeCastLoader(); 
ArrayAdapter<String> adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);       
    f.delegate = this;
    adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
            R.layout.list_item_forecast,
            R.id.list_item_forecast_textview, list);

    f.execute("94043");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState)
{
    View v = inflater.inflate(R.layout.fragment_main, container, false);
    lv = (ListView)v.findViewById(R.id.listview_forecast);
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent in = new Intent(getActivity().getApplicationContext(), DetailView.class);
            in.putExtra("tempData", adapter.getItem(position));
            startActivity(in);
        }
    });
    lv.setAdapter(adapter);
    return v;
}

public void update()
{
    f.delegate = this;
    f.execute("97865");
}

public void processFinish(String[] output)
{
    list.clear();
    for(String s:output)
    {
        list.add(s);
    }
    adapter.notifyDataSetChanged();
    lv.setAdapter(adapter);
}

I left out the aSyncTask class because i already know its returning values correctly and i dont think the problem could be anywhere there. Thanks for your help, im sure its something im just overlooking.

Well, I can see you create a new MainActivityFragment when the NavigationItem clicked. In this way the newly created MainActivityFragment is not the one that you added to your MainActivity when you first launch the app. The new one's onCreate method is not called, so you can't access the adapter in it.

The right way to access a previously added Fragment in an Activity is to use the findFragmentByTag method of the FragmentManager .

I assume you add your MainActivityFragment with a tag like this.

transaction.add(id, maf, MainActivityFragmentTag);

After adding it, you can access it like this.

if(position==2)
{
    mfa = getSupportFragmentManager().findFragmentByTag(MainActivityFragmentTag);
    mfa.update();
}

当您单击刷新按钮时,我假设您正在position =2 MainActivity中调用onNavigationItemSelected()方法。在if条件下,您正在创建MainActivityFragment的新实例并调用它的update()您的适配器正在在MainActivityFragment中的createView()方法中初始化,由于您尚未在此新片段实例上调用show() ,因此不会调用它。请尝试在现有片段本身上调用update()方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM