我有一个带有片段的ViewPager,以及一个Fragment" F"显示ListView" ListF",以及类别列表。
这" ListF"有能力发起活动" A"与另一个ListView" ListA"详细信息(选择类别的项)。
然后,此活动可以选择启动第二个活动" B"这将显示ListView" ListA"的每个项目的信息。来自活动" A"(选择了项的信息)。
所有信息都是从xml,片段" F",活动" A"和活动" B"中解析出来的。
我遇到的问题是当我尝试从活动中导航回来时" B"活动" A",我得到一个 NullPointerException ,说明我通过一个捆绑的一个值(来自Fragment" F"到活动" A"是空的)或类似的。
这是我的片段
public class DirectoryFragment extends Fragment{
DirectoryAdapter adapter;
ListView categoriesList;
Context context;
ArrayList<Category> categories=new ArrayList<Category>();
String tag="directory";
Category category;
JSONManager jmanager;
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
super.onCreateView(inflater, container, savedInstanceState);
View view=inflater.inflate(R.layout.directory_activity, container,false);
categoriesList=(ListView)view.findViewById(R.id.categorieslist);
return view;
}
public DirectoryFragment(){}
public DirectoryFragment(Context context1){
context=context1;
jmanager=new JSONManager(getFragment(),tag);
jmanager.execute();
}
public DirectoryFragment getFragment(){
return this;
}
public void onAttach(Activity activity){
super.onAttach(activity);
}
/*This is the method that displays the listview, I call it from the class that does all the parsing, since I'm using AsyncTask */
public void displayBD(final ArrayList<Category> categories){
try {
if(categories==null || categories.size()==0){
}
} catch (Exception e) {
e.printStackTrace();
}
adapter=new DirectoryAdapter(context,categories);
categoriesList.setAdapter(adapter);
categoriesList.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(android.widget.AdapterView<?> parent,
View view, int position, long id) {
category=categories.get(position);
Bundle bundle=new Bundle();
bundle.putString("title", category.getTitle());
bundle.putString("cid",category.getCid());
Intent intent=new Intent(context,ListingsBD.class);
intent.putExtras(bundle);
startActivityForResult(intent,1); ///launching Activity "A"
}
});
}
}
这是活动&#34; A&#34;
public class ListingsBD extends Activity{
ListingsBDAdapter adapter;
ListView listingList;
ArrayList<Business> listings=new ArrayList<Business>();
Context context;
String title=null,cid=null;
JSONManager jmanager;
Business listing;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=this;
savedInstanceState=this.getIntent().getExtras();
setContentView(R.layout.listings_bd_layout);
android.app.ActionBar actionBar=getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
listingList=(ListView)findViewById(R.id.listingsBD);
cid=savedInstanceState.getString("cid");// this is the line where I get the NPE
title=savedInstanceState.getString("title");
jmanager=new JSONManager(getFragment(),"listingsbd",cid);
jmanager.execute();
}
public ListingsBD getFragment(){
return this;
}
public void onPause(){
super.onPause();
}
public void displayListings(final ArrayList<Business> listings){
try {
if(listings==null || listings.size()==0){
//Retrieve again the data list
}
} catch (Exception e) {
e.printStackTrace();
}
adapter=new ListingsBDAdapter(context,listings);
listingList.setAdapter(adapter);
listingList.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(android.widget.AdapterView<?> parent,
View view, int position, long id) {
listing=listings.get(position);
Bundle bundle=new Bundle();
bundle.putString("name", listing.getName());
bundle.putString("address", listing.getAddress());
bundle.putString("zipCode",listing.getZipCode());
bundle.putString("city", listing.getCity());
bundle.putString("state", listing.getState());
bundle.putString("country", listing.getCountry());
bundle.putString("phone", listing.getPhone());
Intent intent=new Intent(context,SingleListing.class);
intent.putExtras(bundle);
startActivityForResult(intent,1);
}
});
}
}
活动&#34; B&#34;
public class SingleListing extends Activity{
String name=null;
String address=null;
String city=null;
String state=null;
String zipCode=null;
String country=null;
String phone=null;
String imgUrl=null;
TextView nameView,addressView,cityView,phoneView,mobileView,faxView,homeView,tollFreeView,emailView,websiteView;
ImageView image;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_listing_bd_layout);
android.app.ActionBar actionBar=getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
setUp(savedInstanceState);
}
public void setUp(Bundle savedInstanceState){
nameView=(TextView)findViewById(R.id.bd_title);
addressView=(TextView)findViewById(R.id.bd_address);
cityView=(TextView)findViewById(R.id.bd_city);
phoneView=(TextView)findViewById(R.id.bd_phone);
savedInstanceState=this.getIntent().getExtras();
name=savedInstanceState.getString("name");
address=savedInstanceState.getString("address");
city=savedInstanceState.getString("city");
state=savedInstanceState.getString("state");
zipCode=savedInstanceState.getString("zipCode");
country=savedInstanceState.getString("country");
phone=savedInstanceState.getString("phone");;
imgUrl=savedInstanceState.getString("imgUrl");
nameView.setText(name);
if(address.equals(""))
addressView.setVisibility(View.GONE);
else
addressView.setText("Address: "+address);
if(city.equals(""))
addressView.setVisibility(View.GONE);
else
cityView.setText(city+", "+state+", "+zipCode);
if(phone.equals(""))
phoneView.setVisibility(View.GONE);
else
phoneView.setText("Phone: "+phone);
if(mobile.equals(""))
mobileView.setVisibility(View.GONE);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
这是我的日志
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test23/com.example.test23.ListingsBD}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2115)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2153)
at android.app.ActivityThread.access$700(ActivityThread.java:137)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5031)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.test23.ListingsBD.onCreate(ListingsBD.java:36)
at android.app.Activity.performCreate(Activity.java:5058)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2079)
... 11 more
更新:仅当我从操作栏按下后退按钮时才会发生这种情况,如果我从底部菜单中按回来,活动&#34; A&#34;完全显示,不会抛出异常。 任何帮助表示赞赏,如果您需要更多代码或任何示例,请告诉我。谢谢!
答案 0 :(得分:0)
您在savedInstanceState
使用this.getIntent().getExtras()
覆盖了protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=this;
savedInstanceState=this.getIntent().getExtras();
...
}
:
savedInstanceState
onCreate
的目的是:
savedInstanceState 如果在先前关闭之后重新初始化活动,则此Bundle包含最近在onSaveInstanceState(Bundle)中提供的数据。注意:否则为空。
由于您在onCreate
中收到异常,这意味着您的活动已被销毁,并在您导航回来时重新创建。这意味着你应该做的是实现onSaveInstanceState(Bundle),并存储你的活动试图从意图附加中获得的所有参数。
然后您可以在protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=this;
if (savedInstanceState == null)
savedInstanceState=this.getIntent().getExtras();
...
}
中使用以下代码:
this.getIntent().getExtras()
我假设额外的{{1}}意图不会在活动遭到破坏后继续存在,这就是为什么它们是空的。
答案 1 :(得分:0)
搜索和搜索后,我在这篇文章https://stackoverflow.com/a/15933890/2382888中找到了答案。并感谢@Eran。我的应用程序正在创建Activity&#34; A&#34;的新实例,即使它仅重新启动活动,并且由于它是一个新实例,因此它始终为null,因为它就像启动一个新活动即使使用onSavedInstanceState()
方法,也从头开始。
清单中的android:launchMode="singleTop"
行,Docs for Activity
说:&#34;每当有一个&#34;标准&#34;的新意图时activity,创建一个新的类实例来响应该意图。&#34;
因此,在这种情况下,应使用singleTop
,因为:&#34;如果&#34; singleTop&#34;的现有实例活动在目标任务中,将创建一个新实例并将其推送到堆栈中。&#34;
感谢所有帮助过我的人以及那些向我提出问题的人......