0
I have a list fragment which I am adding on create of activity. I have a search functionality which performs search on text change. I don't have a problem when I try to rotate the complete list fragment but when I try to rotate after searching i.e, after I perform filter on the cursor and try to rotate the screen the application crashes. 

My logCat

11-11 18:03:09.929: E/AndroidRuntime(24053): FATAL EXCEPTION: main
11-11 18:03:09.929: E/AndroidRuntime(24053): java.lang.RuntimeException: Unable to resume activity {osm.droid.mat/osm.droid.mat.Accounts}: java.lang.NullPointerException
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2610)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2638)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2111)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3547)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.ActivityThread.access$800(ActivityThread.java:134)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1223)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.os.Looper.loop(Looper.java:137)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.ActivityThread.main(ActivityThread.java:4856)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at java.lang.reflect.Method.invokeNative(Native Method)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at java.lang.reflect.Method.invoke(Method.java:511)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at dalvik.system.NativeStart.main(Native Method)
11-11 18:03:09.929: E/AndroidRuntime(24053): Caused by: java.lang.NullPointerException
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.database.CursorWrapper.getCount(CursorWrapper.java:57)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at osm.droid.fragments.FilterCursorWrapper.<init>(FilterCursorWrapper.java:21)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at osm.droid.fragments.FragmentDisplay.SetAccounts(FragmentDisplay.java:138)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at osm.droid.fragments.FragmentDisplay.access$2(FragmentDisplay.java:121)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at osm.droid.fragments.FragmentDisplay$1.onQueryTextChange(FragmentDisplay.java:173)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.SearchView.onTextChanged(SearchView.java:1192)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.SearchView.access$1900(SearchView.java:93)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.SearchView$11.onTextChanged(SearchView.java:1691)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.TextView.sendOnTextChanged(TextView.java:7398)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.TextView.setText(TextView.java:3730)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.TextView.setText(TextView.java:3585)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.EditText.setText(EditText.java:95)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.TextView.setText(TextView.java:3560)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.widget.TextView.onRestoreInstanceState(TextView.java:3460)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.view.View.dispatchRestoreInstanceState(View.java:12012)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2651)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2651)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2651)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2651)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.view.View.restoreHierarchyState(View.java:11990)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at com.android.internal.view.menu.MenuBuilder.restoreActionViewStates(MenuBuilder.java:358)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:477)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:833)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.Activity.invalidateOptionsMenu(Activity.java:2634)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.ActivityCompatHoneycomb.invalidateOptionsMenu(ActivityCompatHoneycomb.java:29)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.FragmentActivity.supportInvalidateOptionsMenu(FragmentActivity.java:633)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.Fragment.setHasOptionsMenu(Fragment.java:781)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at osm.droid.fragments.FragmentDisplay.onCreateView(FragmentDisplay.java:38)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.support.v4.app.FragmentActivity.onResume(FragmentActivity.java:439)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1199)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.Activity.performResume(Activity.java:5121)
11-11 18:03:09.929: E/AndroidRuntime(24053):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2600)
11-11 18:03:09.929: E/AndroidRuntime(24053):    ... 13 more
11-11 18:03:34.092: I/Process(24053): Sending signal. PID: 24053 SIG: 9
11-11 18:03:34.643: W/ResourceType(24750): Failure getting entry for 0x010802c9 (t=7 e=713) in package 0 (error -75)
11-11 18:03:34.653: W/ResourceType(24750): Failure getting entry for 0x010802c9 (t=7 e=713) in package 0 (error -75)

我的列表片段代码。当我试图旋转屏幕时,onDestroy 被调用了两次。因此光标变为空。我不希望这种情况发生。我知道我可以使用 android:configChanges 但我从以前的答案中知道这不是一个好方法。我能找到更好的解决方案吗?

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState)
    {
         View rootView = inflater.inflate(R.layout.account_list,container, false);
         //Loading the list view
         listView = (ListView) rootView.findViewById(android.R.id.list);
         setHasOptionsMenu(true);       
         return rootView;
    }
    public FragmentDisplay()
    {
        super();
    }
    public FragmentDisplay(Cursor cursor)
    {
        this.cursor = cursor;
    }
    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.accounts, menu); 
        menu.findItem(R.id.action_search).setVisible(true);
        //Attaching query listener to search icon
        SearchView searchView = (SearchView)menu.findItem(R.id.action_search).getActionView();
        searchView.setOnQueryTextListener(queryListener);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        SetAccounts(null);
        //On click of list view item
        listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int id,
                long idInTable) 
            {
                OpenNewAppointment(id);
                //Toast.makeText(getActivity(), "Searching for: " +id+"  Id" +idInTable+ "...", Toast.LENGTH_LONG).show();
            }

          });

    }

    @Override
    public void onAttach(android.app.Activity activity)
    {
        super.onAttach(activity);
        mActivity = activity;
    }
    /*** Creating intent to open new appointment 
     * We will be using the id of the selected item in list view.
     * This method is used to create a new Create Appointment activity and also to send the result back to Create Appointment.
     * @param id
     */
   public void OpenNewAppointment(int id)
   {
       Intent intent =new Intent(mActivity,CreateAppointment.class);
       String accountName=null;
       String crmId=null;

       cursor.moveToPosition(id);
       accountName = (cursor.getString(8));
       crmId = (cursor.getString(0));

       intent.putExtra(Account_Name,new String[] {accountName, crmId});
           if(CreateAppointment.NewActivity)
           {
               //Starts new create appointment activity
               startActivity(intent);
           }
           else
           {
               //Sends the result back to create appointment
               getActivity().setResult(CreateAppointment.RESULT_ACCOUNT,intent);
               getActivity().finish();
           }
   }
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
    }

    /***Set adapter according to the requirement
     * All the records can be loaded into adapter or filtered accounts can be loaded
     * @param strQuery
     */
    private void SetAccounts(String strQuery)
    {
        DbConnection db = null;
        if(strQuery == null)
        {           
            if(cursor == null)
            {
                //If cursor is null database call is made
                db = new DbConnection(mActivity);
                cursor = db.SelectRecords(CRMAccountDbOperations.getTableName(), CRMAccountDbOperations.getColoumnNames(),null,null,null,null,"Name COLLATE NOCASE ASC",null);
            }
            mAdapter = new AdapterClass(cursor, mActivity);

        }
        else if(strQuery != "")
        {
            //Accounts filtered according to the text entered are loaded.
            fwc = new FilterCursorWrapper(cursor, strQuery,8);
            mAdapter = new AdapterClass(fwc, mActivity);
        }   
        else
        {
            mAdapter = new AdapterClass(cursor, mActivity);
        }
        //Set list view and adapter
        listView.setTextFilterEnabled(true);
        listView.setAdapter(mAdapter);
        if(db != null)
        {
            db.CloseDatabase();
        }
    }

    private String currentQuery = null;

    /*** Filtering on text change
     * This method is called every time the text in search text box is changed.
     */
    final private OnQueryTextListener queryListener = new OnQueryTextListener() 
    {       
            @Override
            public boolean onQueryTextChange(String newText) {
                if (TextUtils.isEmpty(newText)) {
                    getActivity().getActionBar().setSubtitle("List");               
                    currentQuery = "";
                } 
                else 
                {
                    getActivity().getActionBar().setSubtitle("List - Searching for: " + newText);
                    currentQuery = newText;

                }   
                SetAccounts(currentQuery);

                return false;
            }

        @Override
        public boolean onQueryTextSubmit(String query) {            
            if (TextUtils.isEmpty(query)) {
                getActivity().getActionBar().setSubtitle("List");               
                currentQuery = "";
            }
            else {
                getActivity().getActionBar().setSubtitle("List - Searching for: " + query);
                currentQuery = query;

            }   
            //SetAccounts(currentQuery);
            return false;
        }
    };

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        cursor.close();
    }
}
4

1 回答 1

0

移动

if(cursor == null)
        {
            //If cursor is null database call is made
            db = new DbConnection(mActivity);
            cursor = db.SelectRecords(CRMAccountDbOperations.getTableName(), CRMAccountDbOperations.getColoumnNames(),null,null,null,null,"Name COLLATE NOCASE ASC",null);
        } 

SetAccounts方法的开头,以便光标在所有条件下都可用。

于 2013-11-11T12:55:23.153 回答