简体   繁体   English

活动开始且未选中复选框时发生NullPointerException

[英]NullPointerException when activity starts and checkbox is not checked

I am trying to implement the following code: 我正在尝试实现以下代码:

 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);}

When I save it 当我保存它

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

Log indicates that it is saved. 日志表明已保存。 Bun when I put 我放的包子

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

comes NullPointerException . 出现NullPointerException

I think it is because nothing is checked and saved when activity starts running. 我认为这是因为活动开始运行时没有检查和保存任何内容。 Am I correct? 我对么? How can I go around? 我该怎么走?

Thank you very much. 非常感谢你。 here we go 开始了

Logcat: 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

Sorry, I forgot. 对不起我忘记了。 Could it be because in my adapter class I have View method with 可能是因为在我的适配器类中,我具有View方法

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

    cbBuy.setOnCheckedChangeListener(myCheckChangList);

    cbBuy.setTag(position);

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

And also 并且

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

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

Sorry I am a new guy and probably don't understand what kind of condradiction could be between checkbox declaration in adapter and in activity. 抱歉,我是一个新手,可能不明白适配器中的复选框声明与活动之间可能存在哪种冲突。 If it is caused because of such contradiciton please explain. 如果是由于这种矛盾引起的,请解释。

Here is the exact coding for onResume and onPause 这是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());

}

The whole code is too big. 整个代码太大。 Let me provide you with onCreate first` public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 让我为您提供onCreate首先`public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.child); 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);
    }
}`

The loader contains checkboxer and looks as follow` public void loader(int val) { 加载程序包含checkboxer,其外观如下: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();
}`

Now in custom BoxAdapter I have the following 现在在自定义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;
  }`

Sorry for inconvenience caused. 不便之处,敬请原谅。 But I want to find out what is going on. 但是我想找出正在发生的事情。

Your sample works with one click. 一键操作您的示例。 Thank you very much. 非常感谢你。 I have tried to update my adapter View method in the following way 我尝试通过以下方式更新我的适配器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;
  }
  `

and made change in onCreate 并在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();
    }`

it still can not save checks when I leave ChildActivity. 我离开ChildActivity时仍然无法保存支票。 I am sad that I can not apply your example and my knoweledge of Android is not enough for operating with View so easy as you do it. 很遗憾,我无法应用您的示例,而我对Android的了解不足以像您一样轻松地使用View进行操作。 If you can further explain me how should I change View to get result I will appreciate it, if no then sorry for your time. 如果您能进一步解释我如何更改视图以获取结果,我将不胜感激。

When the activity is started onResume() will be called. 当活动开始时,将调用onResume()。 So in onResume() just give a check before calling setChecked function so that it should execute only when checkboxer() is not null to ensure it being executed only when the activity is resumed. 因此,在onResume()中,只需在调用setChecked函数之前进行检查即可,以便仅当checkboxer()不为null时才应执行该检查,以确保仅在恢复活动后才执行该检查。

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

Sample activity with checkbox and listview 带有复选框和列表视图的示例活动

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",
        };
}

Sample adapter: 样品适配器:

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");
}
  }

Layout with listview 带有列表视图的布局

<?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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM