java - 无法启动活动 ComponentInfo java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法
问题描述
我正在尝试使用按钮更改为另一个活动。第二个活动(称为 capturar)拍摄一张照片并将其保存在图库中。但是,由于某种原因,每次我尝试使用按钮更改为该活动时,它都会崩溃,我知道问题出在 capturar 的代码上,因为如果我评论所有代码,它就可以工作。
我将放一张我的主要活动代码的图片(我尝试更改为其他活动的意图)和我的 Capturar 活动的代码,我尝试拍照并保存它。
主要活动:
package com.iris.phototask;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.media.Image;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
//Declaramos las variables
public Button btnHorario;
public Button Galeria;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Asignamos el componente al que corresponde la variable
btnHorario = (Button) findViewById(R.id.buttonHorario);
ImageButton imgButtonCamara = findViewById(R.id.imageButtonCamera);
Galeria = (Button) findViewById(R.id.buttonGaleria);
//Creamos un onClickListener para generar un cambio de actividad al pulsar el botón
btnHorario.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Creamos un Intent que nos cambie de ventana
Intent intent = new Intent (MainActivity.this, Horario.class);
startActivity(intent);
}
});
imgButtonCamara.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Creamos un Intent que nos cambie de ventana
Intent intent = new Intent (MainActivity.this, Capturar.class);
startActivity(intent);
}
});
}
}
主要活动 xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/buttonGaleria"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="30dp"
android:background="#8BC34A"
android:text="Galeria"
app:layout_constraintBottom_toTopOf="@+id/buttonHorario"
app:layout_constraintEnd_toEndOf="@+id/buttonHorario"
app:layout_constraintStart_toStartOf="@+id/buttonHorario"
app:layout_constraintTop_toBottomOf="@+id/imageButtonCamera" />
<Button
android:id="@+id/buttonHorario"
android:layout_width="128dp"
android:layout_height="0dp"
android:layout_marginBottom="234dp"
android:background="#8BC34A"
android:text="Horario"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonGaleria" />
<ImageButton
android:id="@+id/imageButtonCamera"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="175dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="32dp"
android:background="#8BC34A"
android:contentDescription="@string/app_name"
app:layout_constraintBottom_toTopOf="@+id/buttonGaleria"
app:layout_constraintEnd_toEndOf="@+id/buttonGaleria"
app:layout_constraintStart_toStartOf="@+id/buttonHorario"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:drawable/ic_menu_camera" />
</androidx.constraintlayout.widget.ConstraintLayout>
捕获活动
package com.iris.phototask;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.UUID;
public class Capturar extends AppCompatActivity {
//Declaración de variables
private static final String TAG = "CapturePicture";
static final int REQUEST_PICTURE_CAPTURE = 1; //Código para referirnos a request capture
private ImageView Imagen; //Declaramos el imageview que tenemos en el xml
private String deviceIdentifier;
String currentPhotoPath; //Un string donde guardaremos el url de la foto
Uri photoURI; //El uri de la foto
@Override
protected void onCreate(Bundle savedInstanceState) {// ************************************************* INICIA ON CREATE PRINCIPAL ********************************************************
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_capturar);
Imagen = findViewById(R.id.imageViewImagen);
Button guardarButton = findViewById(R.id.buttonGuardar);
Button captureButton = findViewById(R.id.buttonCapture);
captureButton.setOnClickListener(buttonCapture);
guardarButton.setOnClickListener(buttonGuardar);
//Si no se habilitó la cámara, deshabilitar el botón de capturar
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
captureButton.setEnabled(false);
}
findViewById(R.id.save_local).setOnClickListener(buttonGuardar);
getInstallationIdentifier();
}// *************************************************************************************************** TERMINA ON CREATE PRINCIPAL *********************************************************
//Si se habilitó la cámara y se pulsa el botón para capturar foto, llamamos al intent que toma la foto, declarado más adelante
private View.OnClickListener buttonCapture = new View.OnClickListener(){
@Override
public void onClick(View view){
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
dispatchTakePictureIntent();
}
}
};
//Creamos una función que genera un intent que solicita IMAGE_CAPTURE
private void dispatchTakePictureIntent(){
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Asegurarse de que hay un camera activity para manejar el intent
if(takePictureIntent.resolveActivity(getPackageManager())!=null){//Inicia if
//Creamos el archivo a donde la foto irá
File photoFile = null;
try{//Inicia Try Catch
//Llamammos a la función para crear la foto
photoFile = createImageFile();
}catch (IOException ex){
//Un error ocurrió al crear el archivo
}//Termina catch
//Si foto file es diferente de nulo
if (photoFile != null){//Empieza if 2
photoURI = FileProvider.getUriForFile(this,"com.example.android.fileprovider",photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent,REQUEST_PICTURE_CAPTURE);
}//Termina if 2
}//Termina if
}
private File createImageFile() throws IOException {//Creamos la función que generará la imagen
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
//SI no existe en directorio para almacenarlo, lo crea.
if (!storageDir.exists())
storageDir.mkdir();
File Imagen = File.createTempFile(
"2019",".jpeg",storageDir
);
currentPhotoPath = Imagen.getAbsolutePath();
return Imagen;
}//Termina función para crear la imagen
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){//Función de iniciar el INTENT con resultados
if (requestCode == REQUEST_PICTURE_CAPTURE && resultCode == RESULT_OK){//Inicia if
Bitmap bitmap;
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),photoURI);
Imagen.setImageBitmap(bitmap);
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}//Termina if
}//Termina función de iniciar el INTENT con resultados
//AL presionar el botón guardar la intentaremos guardar en la librería
private View.OnClickListener buttonGuardar = new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
addToGallery();
}catch (IOException e){
e.printStackTrace();
}
}
};
//Iniciamos la función de añadir a la galería
private void addToGallery() throws IOException{
Intent mediaScanIntent = new Intent (Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File (currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
notifyMediaStoreScanner(f); //función
}
public final void notifyMediaStoreScanner (final File file){
try{
MediaStore.Images.Media.insertImage(this.getContentResolver(),file.getAbsolutePath(), file.getName(),null);
this.sendBroadcast(new Intent (Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
protected synchronized String getInstallationIdentifier(){
if(deviceIdentifier == null){
SharedPreferences sharedPref = this.getSharedPreferences("DEVICE_ID", Context.MODE_PRIVATE);
deviceIdentifier = sharedPref.getString("DEVICE_ID", null);
if(deviceIdentifier == null){
deviceIdentifier = UUID.randomUUID().toString();
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("DEVICE_ID",deviceIdentifier);
editor.commit();
}
}
return deviceIdentifier;
}
}
捕获 xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Capturar">
<ImageView
android:id="@+id/imageViewImagen"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="45dp"
android:layout_marginTop="73dp"
android:layout_marginEnd="45dp"
android:layout_marginBottom="73dp"
app:layout_constraintBottom_toTopOf="@+id/buttonCapture"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:drawable/ic_menu_gallery" />
<Button
android:id="@+id/buttonCapture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="51dp"
android:text="Capturar"
android:background="#8BC34A"
app:layout_constraintBottom_toBottomOf="@+id/buttonGuardar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/buttonGuardar" />
<Button
android:id="@+id/buttonGuardar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="52dp"
android:layout_marginBottom="78dp"
android:text="Guardar"
android:background="#8BC34A"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
安慰:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.iris.phototask, PID: 6499
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.iris.phototask/com.iris.phototask.Capturar}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.iris.phototask.Capturar.onCreate(Capturar.java:54)
at android.app.Activity.performCreate(Activity.java:7224)
at android.app.Activity.performCreate(Activity.java:7213)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2926)
非常感谢,我希望我自己解释一下。
解决方案
空指针异常是由于以下行引起的
findViewById(R.id.save_local).setOnClickListener(buttonGuardar);
因为它找不到 idsave_local
推荐阅读
- javascript - 如何在 Jest 测试中从主源代码文件夹导入模块
- javascript - 您好,我在更新状态时有点卡在反应表单中
- nginx - 静态资源在 Nginx 中通过 k8s Ingress 响应 503
- c# - 从 oidc 客户端获取用户角色
- javascript - 由于位置:固定内容,父 DIv 无法滚动
- kubernetes - 使用 SIZE 列出 Kubernetes 集群中的容器镜像(如 docker image ls)
- python - 当已经有 python 但缺少 pip 时,如何安装 pip?
- python - 在 Python 中使用 Selenium 时如何处理名称中的冒号 (:)
- python - 错误:找不到匹配的分布 re
- google-cloud-platform - 如何在单个 GCE 上设置健康检查 - 内部 IP