有没有办法消除这个空对象引用错误?我正在尝试从扫描仪活动中打开一个底部对话框
Posted
技术标签:
【中文标题】有没有办法消除这个空对象引用错误?我正在尝试从扫描仪活动中打开一个底部对话框【英文标题】:Is there any way to remove this nullobject reference error? I am trying to open a bottom dialog from scanner activity 【发布时间】:2021-07-20 12:51:48 【问题描述】:错误:
E/androidRuntime: FATAL EXCEPTION: main
Process: com.example.swiftpass, PID: 16875
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.swiftpass.ScanPopUpDialog.setPrompt(ScanPopUpDialog.java:47)
at com.example.swiftpass.ScanQrActivity$MyImageAnalyzer.readerBarcodeData(ScanQrActivity.java:170)
at com.example.swiftpass.ScanQrActivity$MyImageAnalyzer.access$200(ScanQrActivity.java:109)
at com.example.swiftpass.ScanQrActivity$MyImageAnalyzer$3.onSuccess(ScanQrActivity.java:142)
at com.example.swiftpass.ScanQrActivity$MyImageAnalyzer$3.onSuccess(ScanQrActivity.java:138)
at com.google.android.gms.tasks.zzn.run(com.google.android.gms:play-services-tasks@@17.2.0:4)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_
android:layout_
android:orientation="vertical">
<RelativeLayout
android:layout_
android:layout_>
<ImageView
android:id="@+id/img_close"
android:layout_
android:layout_
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:src="@drawable/ic_close">
</ImageView>
<TextView
android:id="@+id/txt_type"
android:layout_
android:layout_
android:layout_centerHorizontal="true"
android:layout_marginTop="6dp"
android:text="@string/qr_type"
android:fontFamily="@font/roboto_black"
android:textSize="20dp">
</TextView>
<TextView
android:id="@+id/txt_prompt"
android:layout_
android:layout_
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:layout_marginBottom="10dp"
android:text="@string/qr_prompt"
android:fontFamily="@font/roboto_medium"
android:textSize="18dp">
</TextView>
</RelativeLayout>
</LinearLayout>
底部对话框 java:
包 com.example.swiftpass;
导入android.os.Bundle; 导入 android.view.LayoutInflater; 导入android.view.View; 导入android.view.ViewGroup; 导入android.widget.ImageView; 导入 android.widget.TextView; 导入androidx.annotation.NonNull; 导入androidx.annotation.Nullable;
导入 com.google.android.material.bottomsheet.BottomSheetDialogFragment;
公共类 ScanPopUpDialog 扩展 BottomSheetDialogFragment
//Declaration of Variables
TextView type;
TextView prompt;
ImageView close;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View view = inflater.inflate(R.layout.pop_up_dialog, container, false);
type = view.findViewById(R.id.txt_type);
prompt = view.findViewById(R.id.txt_prompt);
close = view.findViewById(R.id.img_close);
close.setOnClickListener(this::OnClick);
return view;
//This function will listen to button clicks and will call certain functions according to what is pressed by the user
private void OnClick(View view)
switch(view.getId())
case R.id.img_close:
dismiss();
break;
case R.id.txt_prompt:
break;
public void setPrompt(String type, String prompt)
this.type.setText(type);
this.prompt.setText(prompt);
if (type == "TEXT")
this.prompt.setOnClickListener(this::OnClick);
扫描仪活动java:
包 com.example.swiftpass;
导入 androidx.annotation.NonNull; 导入androidx.appcompat.app.AppCompatActivity; 导入androidx.camera.core.CameraSelector; 导入androidx.camera.core.ImageAnalysis; 导入androidx.camera.core.ImageCapture; 导入androidx.camera.core.ImageProxy; 导入androidx.camera.core.Preview; 导入androidx.camera.lifecycle.ProcessCameraProvider; 导入androidx.camera.view.PreviewView; 导入androidx.core.app.ActivityCompat; 导入androidx.core.content.ContextCompat; 导入androidx.fragment.app.FragmentManager;
导入 android.Manifest; 导入 android.annotation.SuppressLint; 导入 android.content.pm.PackageManager; 导入android.graphics.Point; 导入android.graphics.Rect; 导入android.media.Image; 导入android.os.Bundle; 导入android.util.Size; 导入android.widget.Toast;
导入 com.google.android.gms.tasks.OnCompleteListener; 导入 com.google.android.gms.tasks.OnFailureListener; 导入 com.google.android.gms.tasks.OnSuccessListener; 导入 com.google.android.gms.tasks.Task; 导入 com.google.common.util.concurrent.ListenableFuture; 导入 com.google.mlkit.vision.barcode.Barcode; 导入 com.google.mlkit.vision.barcode.BarcodeScanner; 导入 com.google.mlkit.vision.barcode.BarcodeScannerOptions; 导入 com.google.mlkit.vision.barcode.BarcodeScanning; 导入 com.google.mlkit.vision.common.InputImage;
导入 java.util.List; 导入 java.util.concurrent.ExecutionException; 导入 java.util.concurrent.ExecutorService; 导入 java.util.concurrent.Executors;
公共类 ScanQrActivity 扩展 AppCompatActivity
//Declaration of Variables
private ListenableFuture cameraProviderFuture;
private ExecutorService cameraExecutor;
private PreviewView previewView;
private MyImageAnalyzer analyzer;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_qr);
//Assigning of widgets and Setting up of listeners
initializeScan();
cameraProviderFuture.addListener(new Runnable()
@Override
public void run()
try
if (ActivityCompat.checkSelfPermission(ScanQrActivity.this, Manifest.permission.CAMERA) != (PackageManager.PERMISSION_GRANTED))
ActivityCompat.requestPermissions(ScanQrActivity.this, new String [] Manifest.permission.CAMERA, 101);
else
ProcessCameraProvider processCameraProvider = (ProcessCameraProvider) cameraProviderFuture.get();
bindPreview(processCameraProvider);
catch (ExecutionException e)
e.printStackTrace();
catch (InterruptedException e)
e.printStackTrace();
, ContextCompat.getMainExecutor(this));
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
if (requestCode == 101 && grantResults.length > 0)
ProcessCameraProvider processCameraProvider = null;
try
processCameraProvider = (ProcessCameraProvider) cameraProviderFuture.get();
catch (ExecutionException e)
e.printStackTrace();
catch (InterruptedException e)
e.printStackTrace();
bindPreview(processCameraProvider);
private void bindPreview(ProcessCameraProvider processCameraProvider)
Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
preview.setSurfaceProvider(previewView.getSurfaceProvider());
ImageCapture imageCapture = new ImageCapture.Builder().build();
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setTargetResolution(new Size(1280, 720))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
imageAnalysis.setAnalyzer(cameraExecutor, analyzer);
processCameraProvider.unbindAll();
processCameraProvider.bindToLifecycle(this,cameraSelector, preview, imageCapture, imageAnalysis);
public class MyImageAnalyzer implements ImageAnalysis.Analyzer
private FragmentManager fragmentManager;
private ScanPopUpDialog bottomDialog;
public MyImageAnalyzer(FragmentManager fragmentManager)
this.fragmentManager = fragmentManager;
bottomDialog = new ScanPopUpDialog();
@Override
public void analyze(@NonNull ImageProxy imageProxy)
scanBarcode(imageProxy);
private void scanBarcode(ImageProxy imageProxy)
BarcodeScannerOptions options =
new BarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_QR_CODE)
.build();
@SuppressLint("UnsafeExperimentalUsageError") Image mediaImage = imageProxy.getImage();
assert mediaImage != null;
InputImage inputImage =
InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
BarcodeScanner scanner = BarcodeScanning.getClient(options);
Task<List<Barcode>> result = scanner.process(inputImage)
.addOnSuccessListener(new OnSuccessListener<List<Barcode>>()
@Override
public void onSuccess(List<Barcode> barcodes)
// Task completed successfully
readerBarcodeData(barcodes);
)
.addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
// Task failed with an exception
// ...
e.printStackTrace();
)
.addOnCompleteListener(new OnCompleteListener<List<Barcode>>()
@Override
public void onComplete(@NonNull Task<List<Barcode>> task)
imageProxy.close();
);
private void readerBarcodeData(List<Barcode> barcodes)
for (Barcode barcode: barcodes)
Rect bounds = barcode.getBoundingBox();
Point[] corners = barcode.getCornerPoints();
String rawValue = barcode.getRawValue();
int valueType = barcode.getValueType();
switch (valueType)
case Barcode.TYPE_TEXT:
bottomDialog.setPrompt(rawValue, "CLICK TO CONFIRM");
break;
case Barcode.TYPE_CALENDAR_EVENT:
bottomDialog.setPrompt("Calendar Event", "Unsupported Type");
break;
case Barcode.TYPE_CONTACT_INFO:
bottomDialog.setPrompt("Contact Info", "Unsupported Type");
break;
case Barcode.TYPE_DRIVER_LICENSE:
bottomDialog.setPrompt("Driver's License", "Unsupported Type");
break;
case Barcode.TYPE_EMAIL:
bottomDialog.setPrompt("E-mail", "Unsupported Type");
break;
case Barcode.TYPE_GEO:
bottomDialog.setPrompt("Location", "Unsupported Type");
break;
case Barcode.TYPE_ISBN:
bottomDialog.setPrompt("Book Number", "Unsupported Type");
break;
case Barcode.TYPE_PHONE:
bottomDialog.setPrompt("Phone", "Unsupported Type");
break;
case Barcode.TYPE_PRODUCT:
bottomDialog.setPrompt("Product", "Unsupported Type");
break;
case Barcode.TYPE_SMS:
bottomDialog.setPrompt("SMS", "Unsupported Type");
break;
case Barcode.TYPE_URL:
bottomDialog.setPrompt("Link", "Unsupported Type");
break;
case Barcode.TYPE_WIFI:
bottomDialog.setPrompt("Wi-Fi", "Unsupported Type");
break;
default:
bottomDialog.setPrompt("Uknown", "Uknown Type");
if (!bottomDialog.isAdded())
bottomDialog.show(fragmentManager, "");
private void initializeScan()
previewView = findViewById(R.id.previewView);
this.getWindow().setFlags(1024,1024);
cameraExecutor = Executors.newSingleThreadExecutor();
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
analyzer = new MyImageAnalyzer(getSupportFragmentManager());
【问题讨论】:
【参考方案1】:我解决了,代码如下:
package com.example.swiftpass;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
public class ScanPopUpDialog extends BottomSheetDialogFragment
//Declaration of Variables
TextView type;
TextView prompt;
ImageView close;
String stringType;
String stringPrompt;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View view = inflater.inflate(R.layout.pop_up_dialog, container, false);
type = view.findViewById(R.id.txt_type);
type.setText(getStringType());
prompt = view.findViewById(R.id.txt_prompt);
prompt.setText(getStringPrompt());
if (stringPrompt == "CLICK TO CONFIRM")
prompt.setOnClickListener(this::OnClick);
close = view.findViewById(R.id.img_close);
close.setOnClickListener(this::OnClick);
return view;
//This function will listen to button clicks and will call certain functions according to what is pressed by the user
private void OnClick(View view)
switch(view.getId())
case R.id.img_close:
dismiss();
break;
case R.id.txt_prompt:
break;
public void setDialog(String type, String prompt)
/**
* This method is public because it is being called fron the scan qr activity
* this will set the value for the objects stringType and stringPrompt
* this does not return any value thus, the values will be accessed through
* get method
*/
stringType = type;
stringPrompt = prompt;
/**
*These methods are used to access the value set by the setDialog method
*
*/
private String getStringType()
return stringType;
private String getStringPrompt()
return stringPrompt;
【讨论】:
以上是关于有没有办法消除这个空对象引用错误?我正在尝试从扫描仪活动中打开一个底部对话框的主要内容,如果未能解决你的问题,请参考以下文章
NullPointerException 错误尝试在空对象引用上调用虚拟方法错误
尝试从空对象引用上的字段“android.view.View androidx.recyclerview.widget.RecyclerView$b0.a”读取
java.lang.NullPointerException:尝试在 OnPostExecute() 上的空对象引用错误上调用接口方法 - AsyncTask