Android使用java,可变生命周期

Android using java, variable life cycle

提问人:Sebastian Ned 提问时间:9/27/2023 最后编辑:PsythoSebastian Ned 更新时间:9/27/2023 访问量:50

问:

我被困在一个错误上,我有这个代码:

  public String enteredText="";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bts_scan = findViewById(R.id.scanning);
        helpButton = findViewById(R.id.helpButton);
        nextPage = findViewById(R.id.button2);

        bts_scan.setOnClickListener(v->{
            openPopupDialog();
        });
        helpButton.setOnClickListener(v -> {
            contactMail();

        });
        nextPage.setOnClickListener(v -> {
            next();
        });


    }

    private void openPopupDialog() {
        Dialog popupDialog = new Dialog(this);
        popupDialog.setContentView(R.layout.popup);
        Button popupButton = popupDialog.findViewById(R.id.popupButton);
        editText = popupDialog.findViewById(R.id.edit_the_text_of_scan);

        popupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                enteredText = editText.getText().toString();
                if (enteredText.isEmpty()) {
                    Log.e("PopupDialog", "Entered text is empty.");
                } else {
                    Log.d("PopupDialog", "Entered text: " + enteredText);
                    scanCode();
                }
                popupDialog.dismiss();
            }
        });

        popupDialog.show();
    }

    ActivityResultLauncher<ScanOptions> barLauncher=registerForActivityResult(new ScanContract(),result -> {
        if(result.getContents() !=null)
        {

            String scan_results = null;
            try {
                scan_results = scanResults(result.getContents(),enteredText);
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(page1ScanQRCode.this);
            builder.setTitle("Results");
            builder.setMessage(scan_results);
            builder.setPositiveButton("OK", new DialogInterface.OnClickListener()
                    {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i)
                        {
                            dialogInterface.dismiss();
                        }
                    }

            ).show();
        }
        else{
            AlertDialog.Builder builder = new AlertDialog.Builder(page1ScanQRCode.this);
            builder.setMessage("I can't read that output!!");
            builder.show();
        }
    });

  private void scanCode() {
        ScanOptions options = new ScanOptions();
        options.setPrompt("Volume up to flash on");
        options.setBeepEnabled(true);
        options.setOrientationLocked(true);
        options.setCaptureActivity(CaptureAct.class);
        barLauncher.launch(options);
    }

我的 enteredText 变量的生命周期有时不会持续。假设我有时在按下按钮扫描后将输入作为移动应用程序“X32E2”的输入,我的变量变为 null 并且没有将 X32E2 检索到我的 scanResults() 方法,为什么?以及我该如何解决这个问题。

我希望我的变量将 Value 保留到最后。有时它有效,但有时变量值为 null

Java Android 变量

评论

1赞 m0skit0 9/27/2023
如果重新创建活动(例如旋转屏幕),您将丢失所有值,因为它是一个新的对象实例。这就是为什么你应该将逻辑和UI分开(寻找MVVM或其他干净的模式)。
0赞 Sebastian Ned 9/27/2023
所以使用干净的模式总是更好吗?在任何情况下,我的意思是?

答:

0赞 Shaurya Singh 9/27/2023 #1

这背后的主要原因是安道尔活动的生命周期。 当用户与您的应用交互时,Android 可以重新创建活动以响应各种事件。重新创建活动时,可能不会保留其状态,并且所有成员变量都将重置为其默认值,除非您显式保存并还原它。

在代码中,您已将 enteredText 变量声明为字段,但在重新创建活动时不会保存和还原其状态。如果设置 enteredText 的值后重新创建 Activity,但在 scanResults() 中使用它之前,则 enteredText 将重置为其默认值(此处为 null)。

您应该将 enteredText 变量保存在 onSaveInstanceState() 方法的 savedInstanceState Bundle 中,然后在 onCreate() 或 onRestoreInstanceState() 中恢复它。

public String enteredText="";
Button bts_scan, helpButton, nextPage;
EditText editText;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bts_scan = findViewById(R.id.scanning);
    helpButton = findViewById(R.id.helpButton);
    nextPage = findViewById(R.id.button2);

    if (savedInstanceState != null) {
        enteredText = savedInstanceState.getString("EnteredText");
    }

    bts_scan.setOnClickListener(v->{
        openPopupDialog();
    });
    helpButton.setOnClickListener(v -> {
        contactMail();
    });
    nextPage.setOnClickListener(v -> {
        next();
    });
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putString("EnteredText", enteredText);
}

private void openPopupDialog() {
    Dialog popupDialog = new Dialog(this);
    popupDialog.setContentView(R.layout.popup);
    Button popupButton = popupDialog.findViewById(R.id.popupButton);
    editText = popupDialog.findViewById(R.id.edit_the_text_of_scan);

    popupButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            enteredText = editText.getText().toString();
            if (enteredText.isEmpty()) {
                Log.e("PopupDialog", "Entered text is empty.");
            } else {
                Log.d("PopupDialog", "Entered text: " + enteredText);
                scanCode();
            }
            popupDialog.dismiss();
        }
    });

    popupDialog.show();
}

ActivityResultLauncher<ScanOptions> barLauncher=registerForActivityResult(new ScanContract(),result -> {
    if(result.getContents() !=null)
    {

        String scan_results = null;
        try {
            scan_results = scanResults(result.getContents(),enteredText);
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(page1ScanQRCode.this);
        builder.setTitle("Results");
        builder.setMessage(scan_results);
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i)
                    {
                        dialogInterface.dismiss();
                    }
                }

        ).show();
    }
    else{
        AlertDialog.Builder builder = new AlertDialog.Builder(page1ScanQRCode.this);
        builder.setMessage("I can't read that output!!");
        builder.show();
    }
});
private void scanCode() {
  ScanOptions options = new ScanOptions();
  options.setPrompt("Volume up to flash on");
  options.setBeepEnabled(true);
  options.setOrientationLocked(true);
  options.setCaptureActivity(CaptureAct.class);
  barLauncher.launch(options);
}

评论

0赞 Sebastian Ned 9/27/2023
它奏效了,非常感谢你,我现在有了它背后的想法。因此,可以关闭当前活动....所以这就是为什么我们有 onSaveInstanceState 来维护那里的值。谢谢yuuuu