Android - 在片段中,是否在 onStart() 之前调用了 onResume()?
Android - In fragments, Is onResume() called before onStart()?
在我正在构建的应用程序的一部分中,有一个嵌入式 zxing 二维码扫描仪,我在一个片段中使用它。
如果应用尚未授予 Manifest.permission.CAMERA
权限,它会请求权限,然后继续启用扫描仪。
问题是,我在 onResume()
中调用 barcodeView.resume()
并在 onStart()
中请求许可。所以它应该请求 first 和 after 在 onResume()
中调用 barcodeView.resume()
的权限。但显然相反的情况发生了,如果应用程序还没有被授予权限,它会抛出这个异常
java.lang.NullPointerException: Attempt to invoke virtual method 'void
com.journeyapps.barcodescanner.DecoratedBarcodeView.resume()' on a
null object reference
怎么会这样? onResume()
不是在 onStart()
之后调用的吗?
这是我的片段代码:
package com.lab.rafael.smartattendance;
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.BeepManager;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import java.util.List;
public class TakeAttendanceFragment extends Fragment {
private final int CAMERA_PERM_REQUEST = 0;
private static final String TAG = TakeAttendanceFragment.class.getSimpleName();
DecoratedBarcodeView barcodeView = null;
BeepManager beepManager = null;
String lastText;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_take_attendance, container, false);
}
@Override
public void onStart() {
super.onStart();
if(getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
if(ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.CAMERA}, CAMERA_PERM_REQUEST);
} else {
startCamera();
}
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == CAMERA_PERM_REQUEST) {
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startCamera();
}
}
}
private void startCamera() {
try {
if(getView() != null) {
barcodeView = (DecoratedBarcodeView) getView().findViewById(R.id.barcode_scanner);
barcodeView.decodeContinuous(barcodeCallback);
beepManager = new BeepManager(getActivity());
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
private BarcodeCallback barcodeCallback = new BarcodeCallback() {
@Override
public void barcodeResult(BarcodeResult result) {
if(result.getText() == null || result.getText().equals(lastText)) return;
lastText = result.getText();
barcodeView.setStatusText(lastText);
beepManager.playBeepSoundAndVibrate();
}
@Override
public void possibleResultPoints(List<ResultPoint> resultPoints) {
}
};
public void onResume()
{
super.onResume();
barcodeView.resume();
}
public void onPause() {
super.onPause();
barcodeView.pause();
}
}
onStart 在 onResume 之前调用,是的。
权限请求对话框未阻塞,因此当您请求权限时片段生命周期将继续。
所以它会像这样:
- onStart
- 请求许可
- onResume(此时用户还没有授予权限)。
您需要检查 onResume 以查看 barcodeView 是否不为 null 以及权限是否已被授予。
如果权限被授予,onRequestPermissionsResult 将在 onStart 之后立即被调用,因为如果权限被授予它不是异步的,那么这段代码就可以正常工作。
在我正在构建的应用程序的一部分中,有一个嵌入式 zxing 二维码扫描仪,我在一个片段中使用它。
如果应用尚未授予 Manifest.permission.CAMERA
权限,它会请求权限,然后继续启用扫描仪。
问题是,我在 onResume()
中调用 barcodeView.resume()
并在 onStart()
中请求许可。所以它应该请求 first 和 after 在 onResume()
中调用 barcodeView.resume()
的权限。但显然相反的情况发生了,如果应用程序还没有被授予权限,它会抛出这个异常
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.journeyapps.barcodescanner.DecoratedBarcodeView.resume()' on a null object reference
怎么会这样? onResume()
不是在 onStart()
之后调用的吗?
这是我的片段代码:
package com.lab.rafael.smartattendance;
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.BeepManager;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import java.util.List;
public class TakeAttendanceFragment extends Fragment {
private final int CAMERA_PERM_REQUEST = 0;
private static final String TAG = TakeAttendanceFragment.class.getSimpleName();
DecoratedBarcodeView barcodeView = null;
BeepManager beepManager = null;
String lastText;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_take_attendance, container, false);
}
@Override
public void onStart() {
super.onStart();
if(getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
if(ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.CAMERA}, CAMERA_PERM_REQUEST);
} else {
startCamera();
}
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == CAMERA_PERM_REQUEST) {
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startCamera();
}
}
}
private void startCamera() {
try {
if(getView() != null) {
barcodeView = (DecoratedBarcodeView) getView().findViewById(R.id.barcode_scanner);
barcodeView.decodeContinuous(barcodeCallback);
beepManager = new BeepManager(getActivity());
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
private BarcodeCallback barcodeCallback = new BarcodeCallback() {
@Override
public void barcodeResult(BarcodeResult result) {
if(result.getText() == null || result.getText().equals(lastText)) return;
lastText = result.getText();
barcodeView.setStatusText(lastText);
beepManager.playBeepSoundAndVibrate();
}
@Override
public void possibleResultPoints(List<ResultPoint> resultPoints) {
}
};
public void onResume()
{
super.onResume();
barcodeView.resume();
}
public void onPause() {
super.onPause();
barcodeView.pause();
}
}
onStart 在 onResume 之前调用,是的。
权限请求对话框未阻塞,因此当您请求权限时片段生命周期将继续。
所以它会像这样:
- onStart
- 请求许可
- onResume(此时用户还没有授予权限)。
您需要检查 onResume 以查看 barcodeView 是否不为 null 以及权限是否已被授予。
如果权限被授予,onRequestPermissionsResult 将在 onStart 之后立即被调用,因为如果权限被授予它不是异步的,那么这段代码就可以正常工作。