当我点击按钮时,nullpointer异常会引发

时间:2012-06-18 10:28:38

标签: android nullpointerexception android-button

当我点击android上的CheckData button时,它会抛出一个nullpointer exception

SaveData.java

public class SaveData extends Activity implements OnClickListener {     
    static final int DIALOG_ID = 0;

    private Uri mImageCaptureUri;
    private ImageView mImageView;   
    public static class Certificates {
    private Bitmap bmp;

        public Certificates(Bitmap b) {
        bmp = b;
        }
        public Bitmap getBitmap() { return bmp; }
    }

    private static final int PICK_FROM_CAMERA = 1;
    private static final int PICK_FROM_FILE = 2;

    @Override
        protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.addname);

        View button1Click=findViewById(R.id.btn_choose);
        button1Click.setOnClickListener(this);
        View button2Click = findViewById(R.id.Button01add);
        button2Click.setOnClickListener(this);
        View button3Click = findViewById(R.id.Button01check);
        button3Click.setOnClickListener(this);  
    }

        public void onClick(View v){        
        switch(v.getId()){

        case R.id.Button01add:
            showDialog(DIALOG_ID);
            break;

        case R.id.Button01check:
            startActivity(new Intent (SaveData.this,CheckData.class));
            break;
        }

// picking an image from camera or gallery         
            final String [] items           = new String [] {"From Camera", "From SD Card"};                
            ArrayAdapter<String> adapter    = new ArrayAdapter<String> (this, android.R.layout.select_dialog_item,items);
            AlertDialog.Builder builder     = new AlertDialog.Builder(this);

            builder.setTitle("Select Image");
            builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
                public void onClick( DialogInterface dialog, int item ) {
                    if (item == 0) {
                        Intent intent    = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        File file        = new File(Environment.getExternalStorageDirectory(), "tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
                        mImageCaptureUri = Uri.fromFile(file);

                        try {           
                            intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
                            intent.putExtra("return-data", true);                           
                            startActivityForResult(intent, PICK_FROM_CAMERA);
                    }   catch (Exception e) {
                            e.printStackTrace();
                        }           

                        dialog.cancel();
                    } else {
                        Intent intent = new Intent();

                        intent.setType("image/*");
                        intent.setAction(Intent.ACTION_GET_CONTENT);

                        startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE);
                    }
                }
            } );

            final AlertDialog dialog = builder.create();

            mImageView = (ImageView) findViewById(R.id.image1);

            ((Button) findViewById(R.id.btn_choose)).setOnClickListener(new View.OnClickListener() {            
                @Override
                public void onClick(View v) {
                    dialog.show();
                }
            });
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (resultCode != RESULT_OK) return;

            Bitmap bitmap   = null;
            String path     = "";

            if (requestCode == PICK_FROM_FILE) {
                mImageCaptureUri = data.getData(); 
                path = getRealPathFromURI(mImageCaptureUri); //from Gallery 

                if (path == null)
                    path = mImageCaptureUri.getPath(); //from File Manager

                if (path != null) 
                    bitmap  = BitmapFactory.decodeFile(path);
            } else {
                path    = mImageCaptureUri.getPath();
                bitmap  = BitmapFactory.decodeFile(path);
            }

            mImageView.setImageBitmap(bitmap);      
        }

        public String getRealPathFromURI(Uri contentUri) {
            String [] proj      = {MediaStore.Images.Media.DATA};
            Cursor cursor       = managedQuery( contentUri, proj, null, null,null);

            if (cursor == null) return null;

            int column_index    = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

            cursor.moveToFirst();

            return cursor.getString(column_index);
        }

    protected final Dialog onCreateDialog(final int id) {
        Dialog dialog = null;
        switch(id) {
        case DIALOG_ID:
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("Information saved successfully ! Add Another Info?")
            .setCancelable(false)
            .setPositiveButton("No", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {

                    SaveData.this.finish();
              }
            })
        .setNegativeButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
            AlertDialog alert = builder.create(); 
            dialog = alert;
            break;
        default:
        }
        return dialog;
    }
// menu option  
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.layout.mymenu, menu);        
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.item1) {
            Log.d("Option", "Save option is clicked");           
        }
        if(item.getItemId() == R.id.item2) {
            Log.d("Option", "Delete option is clicked");
        }
        if(item.getItemId() == R.id.item3) {
            Log.d("Option", "Exit option is clicked");
        }       
        return super.onOptionsItemSelected(item);       
    }
}

DataManipulator.java:

public class DataManipulator {
public static final String KEY_IMG = "image";

 private DatabaseHelper mDbHelper;
    private SQLiteDatabase mDb;

    private static final String DATABASE_NAME = "DBtest";
    private static final int DATABASE_VERSION = 1;

    private static final String CERTIFICATES_TABLE = "certificates";

    private static final String CREATE_CERTIFICATES_TABLE = "create table "+CERTIFICATES_TABLE+" (" +KEY_IMG+" blob not null) ";

    private final Context mCtx;
    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_CERTIFICATES_TABLE);
        }

        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS "+CERTIFICATES_TABLE);
            onCreate(db);
        }
    }
    public void Reset() { mDbHelper.onUpgrade(this.mDb, 1, 1); }

    public DataManipulator(Context ctx) {
        mCtx = ctx;
        mDbHelper = new DatabaseHelper(mCtx);
    }

    public DataManipulator open() throws SQLException {
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

    public void close() { mDbHelper.close(); }

    public void createCertificatesEntry(Certificates certificates) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        certificates.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, out);
        ContentValues cv = new ContentValues();
        cv.put(KEY_IMG, out.toByteArray());
        mDb.insert(CERTIFICATES_TABLE,  null, cv);
    }
    public Certificates getFirstCertificatesFromDB() throws SQLException {
        Cursor cur = mDb.query(true, CERTIFICATES_TABLE,  new String[] {KEY_IMG}, null, null, null, null, null, null);
        if(cur.moveToFirst()) {
            byte[] blob = cur.getBlob(cur.getColumnIndex(KEY_IMG));
            ByteArrayInputStream inputStream = new ByteArrayInputStream(blob);
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            cur.close();
            return new Certificates(bitmap);
        }
        cur.close();
        return null;
    }    
}

DataManipulator.java:60 certificates.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, out);


CheckData.java:

    public class CheckData extends ListActivity  {     
    TextView selection;
    DataManipulator dm;
    private DataManipulator DataManipulator;

        protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.check);
        dm = new DataManipulator(this);

        LinearLayout layout = new LinearLayout(this);
        ImageView image = new ImageView(this);
        DataManipulator = new DataManipulator(this);

        Certificates testCertificates = new Certificates(BitmapFactory.decodeFile(Context.STORAGE_SERVICE));

        DataManipulator.open();
        DataManipulator.createCertificatesEntry( (Certificates) testCertificates);
        DataManipulator.close(); 

        testCertificates = null;

        DataManipulator.open();
        testCertificates = DataManipulator.getFirstCertificatesFromDB();
        DataManipulator.close();

        image.setImageBitmap(((Certificates) testCertificates).getBitmap());

        setContentView(layout);
    }
}

CheckData.java:29 DataManipulator.createCertificatesEntry( (Certificates) testCertificates);


Logcat错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{list.certificates/list.certificates.CheckData}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
at android.app.ActivityThread.access$600(ActivityThread.java:122)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
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:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at list.certificates.DataManipulator.createCertificatesEntry(DataManipulator.java:60)
at list.certificates.CheckData.onCreate(CheckData.java:29)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)

5 个答案:

答案 0 :(得分:8)

您从certificates.getBitmap()获得空值,因为那里没有位图。在您的初始分配中,您正在尝试解码不存在的文件。使用Context.STORAGE_SERVICE不起作用,它只是一个等于storage的字符串。

例如,如何正确使用存储管理器的代码,请尝试this.

如果您只是尝试解码资源(可绘制,原始等),请使用其他形式的解码:

InputStream is = context.getResources().openRawResource(resID);
Bitmap bitmap = BitmapFactory.decodeStream(is);


<强>更新 假设我知道你要做的是什么,问题是你切换到CheckData活动而没有以任何方式传递选定的位图。活动无法知道要使用的位图,Context.STORAGE_SERVICE不是任何位图,因此您无法对其进行解码。

有关如何将位图传递给新活动的良好答案,请查看here.

简而言之,您可以向mBitmap添加SaveData变量,并将其传递给CheckData

为此,请将SaveData.onClick()中的代码更改为:

case R.id.Button01check:
    Intent intent = new Intent (SaveData.this,CheckData.class);
    intent.putExtra("bitmapData", mBitmap)
    startActivity(intent);
    break; 

并且,在onActivityResult()中,最后添加:

mBitmap = bitmap;

CheckData.onCreate()

Bitmap bmp = getIntent().getExtras().get("bitmapData");
if(bmp != null) {
    Certificates testCertificates = new Certificates(bmp);
} else {
    // Back out gracefully //
}

答案 1 :(得分:2)

问题根:

你的问题就在这一行

 Certificates testCertificates = 
             new Certificates(BitmapFactory.decodeFile(Context.STORAGE_SERVICE));

decodeFile的参数无效,因此返回null。该参数应该是图像文件的路径,而您传递的是用于检索存储服务的常量。

修正:

您已在SaveData活动中拥有位图。您需要通过意图将其传递给CheckData活动。 将位图添加到intent:

   case R.id.Button01check:
        Intent intent = new Intent(this, CheckData.class);
        intent.putExtra("BitmapImage", bitmap);
        startActivity(intent);

然后在CheckData活动中,从intent中检索位图并创建Certificates对象。

Bitmap bitmap = (Bitmap) getIntent().getParcelableExtra("BitmapImage");
Certificates testCertificates = new Certificates(bitmap );

参考:How can I pass a Bitmap object from one activity to another

答案 2 :(得分:1)

certificatesnull,或certificates.getBitmap()正在返回null。添加日志记录以找出哪个。

答案 3 :(得分:0)

在插入数据之前检查证书是否为空:

public void createCertificatesEntry(Certificates certificates) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
  if(certificates !=null)
{
        certificates.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, out);
        ContentValues cv = new ContentValues();
        cv.put(KEY_IMG, out.toByteArray());
        mDb.insert(CERTIFICATES_TABLE,  null, cv);
}
else
{
}

    }

答案 4 :(得分:-1)

一般来说,为了处理异常,我会给你这个提示:

  

当您在logcat上获得异常时,双击(或按   ENTER)这个块中的每个红色行,直到文本   光标转到您获得异常的正确行。

     

然后,一旦你知道你得到了哪些变量,   在点击事件和事件发生时,在那里设置一个断点   onCreate,看看为什么你有这个例外。

然而,你的代码有很多奇怪的东西,例如:

  1. 为什么要用同一种方法拨打setContentView两次?

  2. 为什么要尝试解码名称为Context.STORAGE_SERVICE的位图文件?

  3. 为什么你有一个具有相同名称的类和实例(DataManipulator)?请使用更标准的方式命名字段和变量。