AsyncTask完成后更新片段视图返回nullPointerException

时间:2014-04-22 16:35:29

标签: android android-asynctask fragment

我正在开发一个使用3个片段的应用程序(实际页面)。一个片段用作监听器,另外两个片段用于下载数据,然后设置为textviews。一切都运行正常,直到我认为如果片段视图在异步完成后立即更新/刷新将会很酷。问题是它每次我尝试更新我的片段时都会抛出nullpointer异常。

顺便说一句。我想我可能会采用这种类型的片段管理错误的方法,但它实际上是有效的,我只想要一个很酷的功能,我想也许我不需要重写我的整个程序。

所以这是我的mainActivity.java

公共类MainActivity扩展了FragmentActivity {

//some uninportant initalizations



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Create the adapter that will return a fragment for each of the three
    // primary sections of the app.
    mSectionsPagerAdapter = new SectionsPagerAdapter(
            getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setOffscreenPageLimit(3);
    mViewPager.setAdapter(mSectionsPagerAdapter);
    mViewPager.setCurrentItem(1);
    Autogidas agidas = new Autogidas();


}

public class SectionsPagerAdapter extends FragmentStatePagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = new Pagrindinis();

        switch (position) {
        case 0:         
            return fragment = new Autogidas();
        case 1:
            return fragment = new Pagrindinis();
        case 2:
            return fragment = new AutoPlius();
        default:
            break;
        }
        return fragment;
    }


    @Override
    public int getCount() {
        // Show 3 total pages.
        return 3;
    }




    @Override
    public CharSequence getPageTitle(int position) {
        Locale l = Locale.getDefault();
        switch (position) {
        case 0:
            return getString(R.string.title_section1).toUpperCase(l);
        case 1:
            return getString(R.string.title_section2).toUpperCase(l);
        case 2:
            return getString(R.string.title_section3).toUpperCase(l);
        }
        return null;
    }

}

}

公共类Autogidas扩展了Fragment {

TextView dummyTextViewA;
MainActivity mActivity;
String textToSet;
Context cont;
StringBuffer c;
MySQLiteHelper db;
SharedPreferences prefs;
View rootView;
ArrayList<Car> cars;

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
}

public void setDb(Context con) {
    db = new MySQLiteHelper(con);
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.autogidas, container, false);
    dummyTextViewA = (TextView) rootView.findViewById(R.id.section_label);
    cont = getActivity();
    setDb(cont.getApplicationContext());
    dummyTextViewA.setText("");
    setTextView();//function to return new data from database
    mActivity = new MainActivity();
    Log.i("onCreateView", "onCreateView");
    return rootView;

}

@Override
public void onSaveInstanceState(Bundle outState) {

    super.onSaveInstanceState(outState);
    Log.v("saveInstaceState", "In frag's on save instance state ");

    outState.putString("textView", dummyTextViewA.toString());

}

@Override
public void onViewStateRestored(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onViewStateRestored(savedInstanceState);

    Log.v("restored", "Inside of onRestoreInstanceState");
    if (savedInstanceState != null) {
        dummyTextViewA.setText(savedInstanceState.getString("textView"));
        ;
    }
}

public Context conts(Context con) {
    return cont = con;
}


public void sendNotif(Context con, String data) {
    CheckNetwork.sendNotification(con, data);
}

public void download() {
    //function to start asynctask

}

private class DownloadFilesTask extends AsyncTask<Void, Void, String> {

    @Override
    protected void onPreExecute() {

        super.onPreExecute();

    }

    private boolean checkIfPromoted() {
        //asynctaskstuff
    }

    @Override
    protected String doInBackground(Void... params) {

        //even more asynctask stuff

        }
        return textToSet;
    }

    @Override
    protected void onPostExecute(String result) {


        Autogidas agidas = new Autogidas();
        agidas.getFragmentManager().beginTransaction().detach(agidas).commit();
        agidas.getFragmentManager().beginTransaction().attach(agidas).commit();

        super.onPostExecute(result);

    }

}

}

ALSO片段,用作启动asynctask的触发器

 public class Pagrindinis extends Fragment {  
            /** 
             * The fragment argument representing the section number for this 
             * fragment. 
             */  
            public static final String ARG_SECTION_NUMBER = "section_number";  

            public void DummySectionFragment() {  
            }  

            Context cont;
            TextView dummyTextView;
            Button pradeti; 
            Fragment Autogidas;
            @Override  
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
                View rootView = inflater.inflate(R.layout.pagrindinis, container, false);  
                dummyTextView = (TextView) rootView.findViewById(R.id.section_label);  
                dummyTextView.setText("Pagrindinis :)");  
                pradeti = (Button) rootView.findViewById(R.id.pradeti);
                pradeti.setOnClickListener(new gidasListener());
                cont = getActivity();
                return rootView;  
            }  

            @Override
            public void onSaveInstanceState(Bundle outState) {

                super.onSaveInstanceState(outState);
                Log.v("saveInstaceState", "In frag's on save instance state ");

                outState.putString("textView", dummyTextView.toString());

            }

            @Override
            public void onViewStateRestored(Bundle savedInstanceState) {
                // TODO Auto-generated method stub
                super.onViewStateRestored(savedInstanceState);

                Log.v("restored", "Inside of onRestoreInstanceState");
                if(savedInstanceState!=null){
                dummyTextView.setText(savedInstanceState.getString("textView"));;
                }
            }


            public class gidasListener implements OnClickListener {

                @Override
                public void onClick(View v) {

                    // TODO Auto-generated method stub

                    Log.d("pliusListener", "Button Clicked");
                    Autogidas agidas = new Autogidas();
                    AutoPlius aplius = new AutoPlius();
                    agidas.AddUrls(cont.getApplicationContext());
                    agidas.conts(cont.getApplicationContext());
                    agidas.setDb(cont.getApplicationContext());
                    aplius.AddUrls(cont.getApplicationContext());
                    aplius.conts(cont.getApplicationContext());
                    aplius.setDb(cont.getApplicationContext());
                    if (CheckNetwork.isInternetAvailable(cont.getApplicationContext())) {
                        agidas.download();
                        aplius.download();
                        Log.d("download", "download" );


                    } else {
                        dummyTextView.setText("Prisijunkite prie interneto");
                    }

                }
            }
        }

++ logcat的:

04-22 19:49:24.810: W/dalvikvm(26354): threadid=1: thread exiting with uncaught exception (group=0x40a8ca20)
04-22 19:49:24.830: E/AndroidRuntime(26354): FATAL EXCEPTION: main
04-22 19:49:24.830: E/AndroidRuntime(26354): java.lang.NullPointerException
04-22 19:49:24.830: E/AndroidRuntime(26354):    at com.example.carseeker.Autogidas$DownloadFilesTask.onPostExecute(Autogidas.java:303)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at com.example.carseeker.Autogidas$DownloadFilesTask.onPostExecute(Autogidas.java:1)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at android.os.AsyncTask.finish(AsyncTask.java:602)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at android.os.AsyncTask.access$600(AsyncTask.java:156)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at android.os.Looper.loop(Looper.java:137)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at android.app.ActivityThread.main(ActivityThread.java:4424)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at java.lang.reflect.Method.invokeNative(Native Method)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at java.lang.reflect.Method.invoke(Method.java:511)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
04-22 19:49:24.830: E/AndroidRuntime(26354):    at dalvik.system.NativeStart.main(Native Method)

我正在处理这个问题最近5个小时,我只是不知道如何处理它。

所以也许你可以帮我说一下我应该放在哪里和哪种方法。我认为最好的方法是使用片段附加/分离,但使用它只是发送nullpointer异常。如果你能帮助我,我将非常感激。

2 个答案:

答案 0 :(得分:0)

在你的onPostExecute()中:

Autogidas agidas = new Autogidas();
agidas.getFragmentManager().beginTransaction().detach(agidas).commit();
agidas.getFragmentManager().beginTransaction().attach(agidas).commit();

我认为您正在尝试使用名称agidas分离上一个片段(在gidasListener中创建)并分离新片段(当前agidas)。是这样的吗?如果是这样,我想你可以使用

getFragmentManager().detach(Autogidas.this).commit()

获取对当前片段的引用(您尝试分离的片段),但我不知道将从当前片段中分离出来的片段。

答案 1 :(得分:0)

好的,我已经解决了所有问题。

如果某人正在努力应对动态片段事务,请不要忘记在您的活动中以编程方式添加您的片段。

FragmentTransaction ftransc=getSupportFragmentManager().beginTransaction();
        Autogidas myautogidas=new Autogidas();
        Pagrindinis pagr = new Pagrindinis();
        ftransc.add(viewPager.getId(), myautogidas, "FirstFragment");

ftransc.commit();

我实际上并不知道为什么,因为我的整个应用程序都像魅力一样,但你只需要这样做。

即使添加了片段,您实际上也可能希望更新片段中的数据,例如ASyncTask完成时。这很容易做到!

我找到了一个简单的方法并把它放在我的片段中:

public void refreshData(ArrayList<Car> data) {
        viewPager = MainActivity.getAppPager();
        Log.d("start", "refresh");
        TabsPagerAdapter sk = new TabsPagerAdapter(getFragmentManager());
        viewPager.setAdapter(sk);
        cars = new ArrayList<Car>(data);
        StringBuffer c = new StringBuffer();
        for (Car car : cars) {

            c.append(car + "\n");
        }
        tv.setText(c.toString());
        viewPager.getAdapter().notifyDataSetChanged();

    }

并从我的ASyncTask中调用它:

MySQLiteHelper db = new MySQLiteHelper(MainActivity.getAppContext());
            ArrayList<Car> refreshedArray = db.newCars("agidas");
            Autogidas gidas = (Autogidas) getFragmentManager()
                    .findFragmentByTag("FirstFragment");
            if (gidas != null) {
                gidas.refreshData(refreshedArray);
                Log.d("Fragment", "found");
            }

我正在努力使用notifyDataSetChanged(); - 每当你想通知你的寻呼机应该更新片段时,你必须调用它。但这并不容易。

首先覆盖你的getItemPosition - (它真的没有效率,但它的工作)

@Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

甚至在调用notifydatasetchanged()之后;不会做任何事情。

1.您必须从您的Acitivty获取您的viewPager:

public static ViewPager getAppPager() {
        return viewPager;
    }

从那里检查我的refreshData()方法。

我认为我不必传递整个arrayList,因为我从数据库中获取它,并且onpostexecute仅用作更新我的片段的触发器。

多数民众赞成!:)