我正在开发一个使用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异常。如果你能帮助我,我将非常感激。
答案 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仅用作更新我的片段的触发器。
多数民众赞成!:)