【问题标题】:NullPointerException when activity starts and checkbox is not checked活动开始且未选中复选框时出现 NullPointerException
【发布时间】:2012-10-26 08:11:28
【问题描述】:

我正在尝试实现以下代码:

 public CheckBox checkboxer() {
    final CheckBox box = (CheckBox) findViewById(R.id.cbBox);
    Log.d(LOG_TAG, "make ListView clickable");
    lvMain.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        public void onItemClick(AdapterView<?> parent, View view,
               int position, long id) {              
            box.setChecked(true);
        }
    });       
    return box;
}

   private void savebox(final boolean isChecked) {
    SharedPreferences sharedPreferences = getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putBoolean("check", isChecked);
    editor.commit();
    Log.d(LOG_TAG, "checkbox is saved");
}

private boolean load() { 
SharedPreferences sharedPreferences = getPreferences(Context.MODE_PRIVATE);
return sharedPreferences.getBoolean("check", false);}

当我保存它时

onPause(){
     savebox(checkboxer().isChecked());
} 

日志表示已保存。 当我放面包时

onResume(){
     checkboxer().setChecked(load());
} 

NullPointerException

我认为这是因为活动开始运行时没有检查和保存任何内容。我对么?我怎么能四处走动?

非常感谢。 我们来了

Logcat:

08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime  FATAL EXCEPTION: main
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime  java.lang.RuntimeException: Unable to resume activity {example.CustomAdapter/example.CustomAdapter.ChildActivity}: java.lang.NullPointerException
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2120)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1668)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.os.Handler.dispatchMessage(Handler.java:99)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.os.Looper.loop(Looper.java:123)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.ActivityThread.main(ActivityThread.java:3683)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at java.lang.reflect.Method.invokeNative(Native Method)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at java.lang.reflect.Method.invoke(Method.java:507)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at dalvik.system.NativeStart.main(Native Method)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime  Caused by: java.lang.NullPointerException
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at example.CustomAdapter.ChildActivity.onResume(ChildActivity.java:256)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.Activity.performResume(Activity.java:3832)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110)
08:18:37.830    1773    example.CustomAdapter   ERROR   AndroidRuntime      ... 12 more

对不起,我忘记了。可能是因为在我的适配器类中我有 View 方法与

 CheckBox cbBuy = (CheckBox) view.findViewById(R.id.cbBox);

    cbBuy.setOnCheckedChangeListener(myCheckChangList);

    cbBuy.setTag(position);

    cbBuy.setChecked(p.box);
    return view;`

还有

  OnCheckedChangeListener myCheckChangList = new OnCheckedChangeListener() {
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

      getProduct((Integer) buttonView.getTag()).box = isChecked;
    }
  };

对不起,我是一个新手,可能不明白适配器中的复选框声明和活动中可能存在什么样的矛盾。如果是因为这种矛盾引起的,请解释一下。

这是onResumeonPause 的准确编码

@Override
protected void onResume() {
    super.onResume();
    Log.d(LOG_TAG, "ChildActivity: onResume()");
    DataSourceChild.openToWriteChild();
    checkboxer();

}

@Override
protected void onPause() {
    super.onPause();
    Log.d(LOG_TAG, "ChildActivity: onPause()");

    DataSourceChild.closeChild();

    savebox(checkboxer().isChecked());

}

整个代码太大了。让我先为您提供 onCreate ` public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.child);

    Log.d(LOG_TAG, "ChildActivity: onCreate()");

    child_datasource = new DataSourceChild(this);
    DataSourceChild.openToWriteChild();

    Intent intent = getIntent();

    val_position = intent.getIntExtra("value_1", pos_1);
    val_id = intent.getLongExtra("value_2", pos_2);

    onSelectionMade();

}


public void onSelectionMade() {

    if (val_position == val_id) {

        loader(val_position);
    }
}`

加载器包含复选框,如下所示` public void loader(int val) {

    item_values = child_datasource.readItem(val);

    // определяем адаптер
    boxAdapter = new BoxAdapter(this, item_values);

    // настраиваем список
    lvMain = (ListView) findViewById(R.id.lvMain);

    // выставляем адаптер
    lvMain.setAdapter(boxAdapter);

    // регистратор контекстного меню
    registerForContextMenu(lvMain);

    // метод для работы с checkbox
    checkboxer();

    boxAdapter.notifyDataSetChanged();
}`

现在在自定义 BoxAdapter 中我有以下内容

`  @Override
  public View getView(int position, View convertView, ViewGroup parent) {

    View view = convertView;
    if (view == null) {
      view = lInflater.inflate(R.layout.childitem, parent, false);
    }

    Product p = getProduct(position);
    ((TextView) view.findViewById(R.id.tvDescr)).setText(p.name);
    ((TextView) view.findViewById(R.id.tvPrice)).setText(p.price + "");
    ((ImageView) view.findViewById(R.id.ivImage)).setImageResource(p.image);

    CheckBox cbBuy = (CheckBox) view.findViewById(R.id.cbBox);

    cbBuy.setOnCheckedChangeListener(myCheckChangList);

    cbBuy.setTag(position);

    cbBuy.setChecked(p.box);
    return view;
  }`

对造成的不便深表歉意。但我想知道发生了什么。

您的示例一键即可工作。非常感谢。我尝试通过以下方式更新我的适配器视图方法

`  public View getView(final int position, View convertView, ViewGroup parent) {

    View view = convertView;
    if (view == null) {
      view = lInflater.inflate(R.layout.childitem, parent, false);
    }

    Product p = getProduct(position);

    ((TextView) view.findViewById(R.id.tvDescr)).setText(p.name);
    ((TextView) view.findViewById(R.id.tvPrice)).setText(p.price + "");
    ((ImageView) view.findViewById(R.id.ivImage)).setImageResource(p.image);

    CheckBox cbBuy = (CheckBox) view.findViewById(R.id.cbBox);

    cbBuy.setTag(position);

    cbBuy.setChecked(mIsChecked[position]);

    cbBuy.setOnCheckedChangeListener (new OnCheckedChangeListener() {
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

      mIsChecked[position] = isChecked;
      getProduct((Integer) buttonView.getTag()).box = isChecked;
    }
  });

    return view;
  }
  `

并在 onCreate 中进行了更改

 `    public void loader(int val) {

        item_values = child_datasource.readItem(val);

        lvMain = (ListView) findViewById(R.id.lvMain);

        boolean[] isChecked = new boolean[item_values.size()];
        for (int i = 0; i < item_values.size(); i++) {
            isChecked[i] = false;
        }

        boxAdapter = new BoxAdapter(this, item_values, isChecked);

        lvMain.setAdapter(boxAdapter);

        registerForContextMenu(lvMain);

        boxAdapter.notifyDataSetChanged();
    }`

当我离开 ChildActivity 时它仍然无法保存检查。我很遗憾我无法应用您的示例,而且我对 Android 的了解还不足以像您那样轻松地使用 View 进行操作。如果您能进一步解释我应该如何更改视图以获得结果,我将不胜感激,如果没有,那么对不起您的时间。

【问题讨论】:

  • 你的调试器对空指针有什么看法?
  • 只是猜测...您可以将 Checkbox 框声明为类成员,然后在 onCreate() 中将其初始化为 box = (CheckBox) findViewById(R.id.cbBox);
  • 我将复选框移到方法中,目的是避免空指针
  • 将此行的代码发布给我们:在 example.CustomAdapter.ChildActivity.onResume(ChildActivity.java:256)
  • 别忘了调用 super.onResume(); + 会不会是你没有设置 contentview?

标签: java android checkbox nullpointerexception


【解决方案1】:

当活动开始时 onResume() 将被调用。因此在 onResume() 中,只需在调用 setChecked 函数之前进行检查,以便仅在 checkboxer() 不为空时执行,以确保仅在活动恢复时执行。

onResume(){
     if(checkboxer() != null)
          checkboxer().setChecked(load());
}

带有复选框和列表视图的示例活动

package com.example.checkdoubltap;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class CheckLayoutParams extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.lin);
    ListView list = (ListView) findViewById(R.id.listview);
    boolean[] isChecked = new boolean[countryStrings.length];
    for(int i=0;i<countryStrings.length; i++){
        isChecked[i] = false;
    }
    CheckBoxAdapter adapter = new CheckBoxAdapter(CheckLayoutParams.this, countryStrings, isChecked);

    list.setAdapter(adapter);

}

private String[] countryStrings = { "Afghanistan", "Albania",
        "Algeria", "Andorra", "Angola", "Anguilla", "Antigua and Barbuda",
        "Argentina", "Armenia", "Aruba", "Ascension Island", "Australia",
        "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh",
        "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda",
        "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana",
        };
}

示例适配器:

package com.example.checkdoubltap;

  import android.content.Context;
  import android.util.Log;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.BaseAdapter;
  import android.widget.CheckBox;
  import android.widget.CompoundButton;
  import android.widget.CompoundButton.OnCheckedChangeListener;

  public class CheckBoxAdapter extends BaseAdapter {

private Context mContext;
private String[] mCountries;
private boolean[] mIsChecked;

public CheckBoxAdapter(Context context, String[] countryStrings, boolean[] isChecked) {
    mContext = context;
    mCountries = countryStrings;
    mIsChecked = isChecked;
}

@Override
public int getCount() {
    if(mCountries != null)
        return mCountries.length;
    return 0;
}

@Override
public Object getItem(int position) {
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    CheckBox view = new CheckBox(mContext);
    view.setChecked(load(position));
//  view.setChecked(mIsChecked[position]);
    view.setText(mCountries[position]);
    view.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            Log.d("Check","Changing position to"+position+" "+isChecked);
            mIsChecked[position] = isChecked;
            savebox(position,isChecked);
        }
    });
    return view;
}

private boolean load(int position) { 
    SharedPreferences sharedPreferences = ((Activity) mContext).getPreferences(Context.MODE_PRIVATE);
    return sharedPreferences.getBoolean(""+position, false);
}



private void savebox(int position, final boolean isChecked) {
    SharedPreferences sharedPreferences = ((Activity) mContext).getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putBoolean(""+position, isChecked);
    editor.commit();
    Log.d(TAG, "checkbox is saved");
}
  }

使用列表视图布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ListView 
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:id="@+id/listview"
>
</ListView>
</LinearLayout>

【讨论】:

  • 我也是这么想的。它运行但在检查复选框时不保存
  • 你在onPause中有保存框功能吗?那功能正常吗?在这种情况下 onResume 它应该正确设置检查
  • 我只能猜测它运行正常是因为 Log.d(LOG_TAG, "checkbox is saved");在保险箱方法的末尾
  • 当我在没有 onResume{checkboxer().setChecked(load())} 的情况下运行代码时,它会显示日志
  • 你能看看我编辑的问题吗?可能是我的适配器引起的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多