我有一个无法解决的问题。当我在同一个包中存储许多数据时,我的导航抽屉(与包的位置匹配的项目)崩溃。
这是一个例子:
public void SelectItem(int possition) {
Fragment fragment = null;
Bundle args = new Bundle();
switch (possition) {
case 2:
fragment = new search();
//args.putString(FragmentThree.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 3:
fragment = new com.tutecentral.navigationdrawer.Menu();
String DishText = ((Spinner) findViewById(R.id.spinnerSetting)). getSelectedItem().toString();
args.putString("DishType", DishText);
TextView text=(TextView)findViewById(R.id.price);
int priceDish=Integer.parseInt(text.getText().toString());
args.putInt("price", priceDish);
break;
case 4:
fragment = new bill_send();
TextView textprice=(TextView)findViewById(R.id.TotalFieldMenu);
int priceTotal=Integer.parseInt(textprice.getText().toString());
args.putInt("Total_price", priceTotal);
//args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 5:
fragment = new tables();
//args.putString(FragmentThree.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 7:
fragment = new about();
//args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 8:
fragment = new setting();
//args.putString(FragmentThree.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 9:
fragment = new FragmentOne();
//args.putString(FragmentOne.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 10:
fragment = new FragmentTwo();
//args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 11:
fragment = new FragmentThree();
//args.putString(FragmentThree.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 12:
fragment = new FragmentOne();
//args.putString(FragmentOne.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
case 13:
fragment = new FragmentThree();
//args.putString(FragmentThree.ITEM_NAME, dataList.get(possition).getItemName());
//args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition).getImgResID());
break;
default:
break;
}
if(com.tutecentral.navigationdrawer.Menu.actionBar!=null){
if (com.tutecentral.navigationdrawer.Menu.actionBar.isShowing()){
com.tutecentral.navigationdrawer.Menu.actionBar.removeAllTabs();
}
}
fragment.setArguments(args);
FragmentManager frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
mDrawerList.setItemChecked(possition, true);
setTitle(dataList.get(possition).getItemName());
mDrawerLayout.closeDrawer(mDrawerList);
}
请注意,当我删除case4或3中的包(使用其中一个)时,应用程序可以运行。并且错误说明:项目上的导航抽屉单击空指针异常。
我收到数据的两个片段是:
public class bill_send extends Fragment {
public bill_send(){
// TODO Auto-generated constructor stub
}
TextView textViewPrice;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view=inflater.inflate(R.layout.bill_send, container, false);
textViewPrice=(TextView) view.findViewById(R.id.produitPriceBill);
int priceTotal=getArguments().getInt("Total_price");
textViewPrice.setText(String.valueOf(priceTotal));
return view;
}
}
第二个(菜单()):
final int PriceEdited = getArguments().getInt("price");
final String NameDish=getArguments().getString("DishType");
textViewPrice.setText(String.valueOf(PriceEdited));
price=Integer.parseInt(textViewPrice.getText().toString());
有人可以帮忙吗?谢谢。
这是Logcat:
04-11 18:24:39.102: D/dalvikvm(1069): GC_FOR_ALLOC freed 39K, 5% free 2889K/3016K, paused 53ms, total 56ms
04-11 18:24:39.322: I/dalvikvm-heap(1069): Grow heap (frag case) to 13.447MB for 11059216-byte allocation
04-11 18:24:39.382: D/dalvikvm(1069): GC_FOR_ALLOC freed 2K, 1% free 13686K/13820K, paused 55ms, total 55ms
04-11 18:24:40.992: D/gralloc_goldfish(1069): Emulator without GPU emulation detected.
04-11 18:24:49.632: I/Choreographer(1069): Skipped 873 frames! The application may be doing too much work on its main thread.
04-11 18:24:49.982: I/Choreographer(1069): Skipped 40 frames! The application may be doing too much work on its main thread.
04-11 18:25:12.822: I/Choreographer(1069): Skipped 32 frames! The application may be doing too much work on its main thread.
04-11 18:25:13.032: I/Choreographer(1069): Skipped 30 frames! The application may be doing too much work on its main thread.
04-11 18:25:13.242: I/Choreographer(1069): Skipped 39 frames! The application may be doing too much work on its main thread.
04-11 18:25:13.462: I/Choreographer(1069): Skipped 47 frames! The application may be doing too much work on its main thread.
04-11 18:25:15.622: D/AndroidRuntime(1069): Shutting down VM
04-11 18:25:15.622: W/dalvikvm(1069): threadid=1: thread exiting with uncaught exception (group=0xb3af2b90)
04-11 18:25:15.632: E/AndroidRuntime(1069): FATAL EXCEPTION: main
04-11 18:25:15.632: E/AndroidRuntime(1069): Process: com.tutecentral.navigationdrawer, PID: 1069
04-11 18:25:15.632: E/AndroidRuntime(1069): java.lang.NullPointerException
04-11 18:25:15.632: E/AndroidRuntime(1069): at com.tutecentral.navigationdrawer.MainActivity.SelectItem(MainActivity.java:130)
04-11 18:25:15.632: E/AndroidRuntime(1069): at com.tutecentral.navigationdrawer.MainActivity$DrawerItemClickListener.onItemClick(MainActivity.java:241)
04-11 18:25:15.632: E/AndroidRuntime(1069): at android.widget.AdapterView.performItemClick(AdapterView.java:299)
04-11 18:25:15.632: E/AndroidRuntime(1069): at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
04-11 18:25:15.632: E/AndroidRuntime(1069): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
04-11 18:25:15.632: E/AndroidRuntime(1069): at android.widget.AbsListView$3.run(AbsListView.java:3638)
04-11 18:25:15.632: E/AndroidRuntime(1069): at android.os.Handler.handleCallback(Handler.java:733)
04-11 18:25:15.632: E/AndroidRuntime(1069): at android.os.Handler.dispatchMessage(Handler.java:95)
04-11 18:25:15.632: E/AndroidRuntime(1069): at android.os.Looper.loop(Looper.java:137)
04-11 18:25:15.632: E/AndroidRuntime(1069): at android.app.ActivityThread.main(ActivityThread.java:4998)
04-11 18:25:15.632: E/AndroidRuntime(1069): at java.lang.reflect.Method.invokeNative(Native Method)
04-11 18:25:15.632: E/AndroidRuntime(1069): at java.lang.reflect.Method.invoke(Method.java:515)
04-11 18:25:15.632: E/AndroidRuntime(1069): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
04-11 18:25:15.632: E/AndroidRuntime(1069): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
04-11 18:25:15.632: E/AndroidRuntime(1069): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:2)
在Fllo的帮助下,我可以解决我的问题。实际上问题在于主要的工作是做太多的工作,这就是线程的解决方案就像魅力一样:
send_bill片段中的:
public void setTotal(final String text){
textViewPrice.setText(文本);
}
public void sentTotal(){
new MyThread().execute();
}
public class MyThread extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... strings) {
// TODO Auto-generated method stub
Bundle b=getArguments();
totalValue=b.getString("Total");
return null;
}
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
setTotal(totalValue);
}
}
然后在菜单片段中:
1声明界面:
FragSendTotal mCallback;
public interface FragSendTotal{
public Bundle sendTotal(String text);
}
2将数据从片段菜单发送到片段bill_dend的按钮:
public void onClick(View v) {
switch (v.getId()) {
case R.id.commander:
tt =totalPrice.getText().toString();
mCallback.sendTotal(tt);
break;
最后在主要活动中:
1获得捆绑包:
@Override
public Bundle sendTotal(String total) {
// TODO Auto-generated method stub
Bundle bundleFrag=new Bundle();
bundleFrag.putString("Total", total);
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(null).commit();
return bundleFrag;
}
2在实例化并显示send_bill片段时使用它:
fragment.setArguments(sendTotal(com.tutecentral.navigationdrawer.Menu.tt));
frgManager.beginTransaction().add(R.id.content_frame, new bill_send(), "fragBill").commit();
frgManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(null).commit();
((bill_send) fragment).sentTotal();
感谢Fllo的帮助,我希望这个问题可以帮助其他人。
答案 1 :(得分:1)
我正在撰写评论,但似乎解释问题的时间太短了。所以我会尽力帮助你,但是如果我不知道你的应用程序的设计会很难,但试试吧。
你正在做很多关于你的活动和你的片段的工作 - 你在你的情况下使用了太多的资源:这会导致Shutting Down
。
首先,您应该为每个片段创建一个实例。这允许您拥有:一个单独的地方,其中片段使用的所有参数都可以捆绑在一起,并且每次实例化一个新的时候都不必编写代码(带有包)片段即可。
相关:Best practice for instantiating a new Android Fragment
对于每个片段,您需要创建一个实例,例如在Menu片段中执行如下操作:
public static Menu newInstance(int price, String type) {
Menu frag = new Menu();
Bundle args = new Bundle();
args.putInt("PRICE", price);
args.putString("TYPE", type);
frag.setArguments(args);
return frag;
}
这可以避免您在Activity中创建一个Bundle。要传递活动中的数据,您应该执行以下操作:
...
case 3:
String dish_type = ((Spinner) findViewById(R.id.spinnerSetting)).getSelectedItem().toString();
TextView text_price = (TextView) findViewById(R.id.price);
int priceDish = Integer.parseInt(text.getText().toString());
fragment = new Menu.newInstance(dish_type, text_price);
break;
...
在Google Documentation中,您有一个很好的例子,也有this SO's post。
其次,请记住Bundle有一个限制:限制为500kb 。但是,我认为这不仅仅是针对整数和字符串的情况,但知道这一点很好 与:Is there some limits in android' bundle?
相关第三,在使用Log语句替换片段之前执行检查条件,以查看您的Spinner是否为null
。要避免NullPointerException
,您需要创建一个后台线程。我认为这与错误有关:“应用程序可能在其主线程上执行了太多工作 ”。也许,重写您的应用程序更轻:使用ActionBar中的(默认)选项菜单作为“其他选项”,“设置”,“帮助”和“关于”的辅助项目。您可以避免创建多个项目并使NavigationDrawer更轻
您必须检查您的布局,查看微调器是否具有正确的ID,如果它是相同的,则必须在您的活动中。我真的不确定,但你可以尝试做一个新的线程来显示你的片段(我没有测试过,所以我真的不知道你是否可以):
final Runnable changeFrag = new Runnable() {
public void run() {
// launch your fragment here or call a method to do so
handler.postDelayed(this, timeout);
}
};
handler.postDelayed(changeFrag, timeout);
但是,我认为正确的解决方案是让您的活动更轻松。
我真的希望它会对你有所帮助 祝你好运,好开心。
注意:下一个问题(如果你有的话)会更好地编写你的应用程序的上下文:你要做什么,你尝试了什么,什么是应用程序。因为我无法弄清楚你是如何构建它的。但是,您不必告诉所有上下文(有时项目有秘密^^),但只需要了解一下是什么问题。无论如何......