KC Chai
KC Chai

Reputation: 1617

Android AsyncTask On Exit Exception

I'm having problems with my Asynctask. Whenever I exit my app with my BACK button, it just caught an exception. Please take a look at my codes. Please help me to correct it. Thanks.

AndroidFragment.java

    public class AndroidFragment extends SherlockListFragment  implements ActionBar.TabListener{

    private ProgressDialog pDialog;
    static final String URL = "https://dl.dropbox.com/s/86p8y5y2birua9n/test1.xml";
    // XML node keys
    static final String KEY_ITEM = "item"; // parent node
    static final String KEY_ID = "id";
    static final String KEY_NAME = "name";
    static final String KEY_COST = "cost";
    static final String KEY_DESC = "description";
    ArrayList<HashMap<String, String>> menuItems;
    ListAdapter adapter;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        new loadListView().execute();   
    return super.onCreateView(inflater, container, savedInstanceState);

    }

    public class loadListView extends AsyncTask<Integer, String, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();



        }

        @Override
        protected String doInBackground(Integer... args) {
            // updating UI from Background Thread
            menuItems = new ArrayList<HashMap<String, String>>();


            XMLParser parser = new XMLParser();
            String xml = parser.getXmlFromUrl(URL); // getting XML
            Document doc = parser.getDomElement(xml); // getting DOM element

            NodeList nl = doc.getElementsByTagName(KEY_ITEM);
            // looping through all item nodes <item>
            for (int i = 0; i < nl.getLength(); i++) {
                // creating new HashMap
                HashMap<String, String> map = new HashMap<String, String>();
                Element e = (Element) nl.item(i);
                // adding each child node to HashMap key => value
                map.put(KEY_ID, parser.getValue(e, KEY_ID));
                map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
                map.put(KEY_COST, "Rs." + parser.getValue(e, KEY_COST));
                map.put(KEY_DESC, parser.getValue(e, KEY_DESC));

                // adding HashList to ArrayList
                menuItems.add(map);
            }




                    return null;
                }   


        @Override
        protected void onPostExecute(String args) {


            adapter = new SimpleAdapter(getActivity(), menuItems,
                    R.layout.list_item,
                    new String[] { KEY_NAME, KEY_DESC, KEY_COST }, new int[] {
                            R.id.name, R.id.desciption, R.id.cost });


            setListAdapter(adapter);
            //pDialog.dismiss();
            }
        }

     @Override
     public void onDestroy() {
         if (adapter  != null) {
         setListAdapter(null);
         }
         super.onDestroy();
     }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        ft.add(android.R.id.content, this);

        ft.attach(this);
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.detach(this);
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }

}

LOGCAT :

10-06 00:17:55.750: E/AndroidRuntime(8780): FATAL EXCEPTION: main
10-06 00:17:55.750: E/AndroidRuntime(8780): java.lang.NullPointerException
10-06 00:17:55.750: E/AndroidRuntime(8780):     at android.widget.SimpleAdapter.<init>(SimpleAdapter.java:85)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at in.wptrafficanalyzer.actionbarsherlocknavtab.AndroidFragment$loadListView.onPostExecute(AndroidFragment.java:96)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at in.wptrafficanalyzer.actionbarsherlocknavtab.AndroidFragment$loadListView.onPostExecute(AndroidFragment.java:1)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at android.os.AsyncTask.finish(AsyncTask.java:602)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at android.os.AsyncTask.access$600(AsyncTask.java:156)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at android.os.Looper.loop(Looper.java:137)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at android.app.ActivityThread.main(ActivityThread.java:4512)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at java.lang.reflect.Method.invokeNative(Native Method)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at java.lang.reflect.Method.invoke(Method.java:511)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:982)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
10-06 00:17:55.750: E/AndroidRuntime(8780):     at dalvik.system.NativeStart.main(Native Method)

New LOGCAT :

10-06 00:49:26.094: E/AndroidRuntime(10780): FATAL EXCEPTION: main
10-06 00:49:26.094: E/AndroidRuntime(10780): java.lang.NullPointerException
10-06 00:49:26.094: E/AndroidRuntime(10780):    at android.widget.SimpleAdapter.<init>(SimpleAdapter.java:85)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at in.wptrafficanalyzer.actionbarsherlocknavtab.AppleFragment$loadListView.onPostExecute(AppleFragment.java:97)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at in.wptrafficanalyzer.actionbarsherlocknavtab.AppleFragment$loadListView.onPostExecute(AppleFragment.java:1)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at android.os.AsyncTask.finish(AsyncTask.java:602)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at android.os.AsyncTask.access$600(AsyncTask.java:156)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at android.os.Handler.dispatchMessage(Handler.java:99)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at android.os.Looper.loop(Looper.java:137)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at android.app.ActivityThread.main(ActivityThread.java:4512)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at java.lang.reflect.Method.invokeNative(Native Method)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at java.lang.reflect.Method.invoke(Method.java:511)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:982)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
10-06 00:49:26.094: E/AndroidRuntime(10780):    at dalvik.system.NativeStart.main(Native Method)

Upvotes: 3

Views: 743

Answers (3)

toadzky
toadzky

Reputation: 3846

my guess is that the fragment isn't attached to the activity when the simple adapter is created. that is the only thing in your new SimpleAdapter call that could return null. move the asynctask request to onViewCreated and see what happens.

UPDATE: I checked the source code from the SimpleAdapter file. the line throwing the error is trying to create a LayoutInflater from the context you pass in (the activity). that is returning null, so your getactivity() call is returning null.

ANSWER: Since getActivity() will return null if the fragment is not attached, use the application context to create the SimpleAdapter. You can get the application context from the LayoutInflater passed to onCreateView.

Upvotes: 0

Kirill Lebedev
Kirill Lebedev

Reputation: 650

The problem is that your list takes to much time to load and parse. Your activity is already destroyed when

protected void onPostExecute(String args)

is called.

But if activity is already destroyed then you do not need to update UI. The simplest solution will be:

@Override protected void onPostExecute(String args) {

        if (getActivity() != null) {
            ListAdapter adapter = new SimpleAdapter(getActivity(), menuItems,
                R.layout.list_item,
                new String[] { KEY_NAME, KEY_DESC, KEY_COST }, new int[] {
                        R.id.name, R.id.desciption, R.id.cost });


            setListAdapter(adapter);
               //pDialog.dismiss();

        }
    }

Upvotes: 1

Chet
Chet

Reputation: 1225

Declare Listadapter adapter at Class Level

   @Override
        public void onDestroy() {
            if (adapter  != null) {
            setListAdapter(null);
            }
            super.onDestroy();
        }

Upvotes: 0

Related Questions