从另一个Activity导航回来时NPE在Activity中

时间:2014-08-14 20:23:54

标签: android android-activity nullpointerexception

我有一个带有片段的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;完全显示,不会抛出异常。 任何帮助表示赞赏,如果您需要更多代码或任何示例,请告诉我。谢谢!

2 个答案:

答案 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;

感谢所有帮助过我的人以及那些向我提出问题的人......