【问题标题】:How to avoid Null Pointer Exception in Two Activities Communication两个活动通信中如何避免空指针异常
【发布时间】:2020-01-27 03:00:36
【问题描述】:

我正在尝试调用另一个类中的方法,当在同样位于 AlertDialogInput 中的 AutoCompleteTextView 中单击项目时,该方法将填充 TextViews。

但是当我点击一个项目时我的应用程序崩溃了。

我是 android 开发的新手,因此非常感谢任何帮助。

自定义警报对话框 警报对话框类

public static class ToPrintAccountSearchDialog extends AppCompatDialogFragment
    {
        private AutoCompleteTextView toprint_auto_account_search_dialog;

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

            LayoutInflater layoutInflater = getActivity().getLayoutInflater();
            View view = layoutInflater.inflate(R.layout.for_printing_account_search_dialog_layout, null);
            builder.setView(view);
            builder.setTitle("Search Account");

            List<ForBillPrintConsumerEntities> forBillPrintConsumerEntities = new ArrayList<>();
            toprint_auto_account_search_dialog = view.findViewById(R.id.Alert_Dialog_Account_Auto_Search);
            ForPrintingConsumerAccountSearchAdapter forPrintingConsumerAccountSearchAdapter = new ForPrintingConsumerAccountSearchAdapter(getActivity(), forBillPrintConsumerEntities);
            toprint_auto_account_search_dialog.setThreshold(1);
            toprint_auto_account_search_dialog.setAdapter(forPrintingConsumerAccountSearchAdapter);
                toprint_auto_account_search_dialog.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 
                {
                    PrintBill printBill = new PrintBill();
                    printBill.getotherinformationbyaccountforprinting();
                }
            });

            return builder.create();
        }
    }

这是显示 AlertDialogInput 的代码 主要活动


Account_No = findViewById(R.id.toprint_Account_No_Value);
        Account_No.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {
                forPrintAccountSearchDialog();
            }
        });

public void forPrintAccountSearchDialog()
    {
        ToPrintAccountSearchDialog toPrintAccountSearchDialog = new ToPrintAccountSearchDialog();
        toPrintAccountSearchDialog.show(getSupportFragmentManager(), "ToPrintAccountSearchDialog");
    }

这是我想要在 AlertDialog AutocompleteTextview 中单击项目时调用的方法,该项目也在主活动中,以填充我的主活动中的文本视图

public void getotherinformationbyaccountforprinting()
    {
        ConsumerAccountForPrinting = toprint_auto_account_search_dialog.getText().toString();
        db = new DatabaseHelper(getApplicationContext());
        sqLiteDatabase = db.getReadableDatabase();
        Cursor cursor = db.ForPrintingGetOtherInfoByAccount(ConsumerAccountForPrinting, sqLiteDatabase);
        if (cursor.moveToFirst()) {
            do {
                String ACCOUNT_NUMBER = cursor.getString(0);
                String NAME = cursor.getString(1);
                String ADDRESS = cursor.getString(2);
                Account_No.setText(ACCOUNT_NUMBER);
                Name.setText(NAME);
                Address.setText(ADDRESS);
                }
            while (cursor.moveToNext());
        }
    }

数据库助手

public Cursor ForPrintingGetOtherInfoByAccount(String keyword, SQLiteDatabase sqLiteDatabase)
    {
        String [] projections = {ForPrintingConsumerOtherInfoAdapterByAccount.getOtherInfoForPrintingByAccount.ACCOUNT_NO,
                ForPrintingConsumerOtherInfoAdapterByAccount.getOtherInfoForPrintingByAccount.NAME,
                ForPrintingConsumerOtherInfoAdapterByAccount.getOtherInfoForPrintingByAccount.ADDRESS,
                String selection = ConsumerListOtherInfoAdapterByAccount.getOtherInfoForListByAccount.CONSUMER_ACCOUNT_NO+" LIKE ?";
        String [] selection_args = {keyword};
        Cursor cursor = sqLiteDatabase.query(ForPrintingConsumerOtherInfoAdapterByAccount.getOtherInfoForPrintingByAccount.TABLE_NAME,projections,selection,selection_args,null,null,null);
        return cursor;
    }

在数据库助手内部调用的投影

public class ForPrintingConsumerOtherInfoAdapterByAccount
{
    public static abstract class getOtherInfoForPrintingByAccount
    {
        public static final String TABLE_NAME = "toPrintBill";
        public static final String ACCOUNT_NO = "account_no";
        public static final String NAME = "name";
        public static final String ADDRESS = "address";
    }
}

点击时弹出文本视图提示对话框

当我输入数字时,autocompletetextview 将建议从 sqlite 数据库表中具有相同值的数据

但是当我点击一个项目时会发生这种情况


java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.AutoCompleteTextView.getText()' on a null object reference
        at com.vicjames.qiimeterreader.PrintBill.getotherinformationbyaccountforprinting(PrintBill.java:224)
        at com.vicjames.qiimeterreader.PrintBill$ToPrintAccountSearchDialog$1.onItemClick(PrintBill.java:189)
        at android.widget.AutoCompleteTextView.performCompletion(AutoCompleteTextView.java:1017)

如何在我的警报对话框类和主要活动之间创建通信,以便我可以使用该方法?

【问题讨论】:

  • 请查看this answer。在这个答案中,他们使用了 Fragment。您可以在Dialogs 中使用interface 实现类似的含义

标签: android android-alertdialog


【解决方案1】:

使用LocalBroadcastManager。在你的activity的onResume方法中注册一个receiver,具体的action,比如"executeMainActivityCode"就可以了。为此,您需要这样的东西:

onResume:

LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, new IntentFilter("executeMainActivityCode"));

onPause(不要忘记这个):

LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver));

从您的对话框中,调用此代码:

LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent("executeMainActivityCode"));

在接收器中,在onReceive 中调用你的方法,你就可以开始了。

【讨论】:

  • 还有一个问题,先生,ConsumerAccountForPrinting = toprint_auto_account_search_dialog.getText().toString(); 由于 toprint_auto_account_search_dialog AutoCompleteTextview 在警报对话框中而不在 MainActivity 中,我得到一个空指针异常。我该如何解决这个问题
【解决方案2】:

你打电话给findViewById 太早了:

Account_No = findViewById(R.id.toprint_Account_No_Value);

在构建 Activity 时调用它。尝试将getotherinformationbyaccountforprinting 中的Account_No 替换为findViewById(R.id.toprint_Account_No_Value),或者在调用setContentView 后在onCreate 中设置Account_No

【讨论】:

  • 这不是问题,问题是当我尝试执行getotherinformationbyaccountforprinting() 时出现空对象异常
  • 好吧,我知道了——你尝试我的建议了吗?您调用findViewById 太早了,它将Account_No 设置为null,所以当您在getotherinformationbyaccountforprinting 中访问Account_No 时,它是null。如果你像我建议的那样在getotherinformationbyaccountforprinting 中调用它,那么此时它不应该是null
【解决方案3】:

正如我在评论中建议的那样,您可以使用interface 在活动/片段/适配器/等之间进行通信。

1。创建接口

public interface DataTransfer{
    void sendData(String data); //change parameter to whatever you want
}

2。在您的活动中实现接口

3。在alertDialog中传递接口

ToPrintAccountSearchDialog toPrintAccountSearchDialog = 
    new ToPrintAccountSearchDialog(this);  
    // here this will pass the implemented interface

4。在您的对话框中使用构造函数接收接口


private DataTransfer dataTransfer;

public ToPrintAccountSearchDialog(DataTransfer dataTransfer){
    this.dataTransfer = dataTransfer;
}

5。使用此 dataTransfer 将数据传递给活动

dataTransfer.sendData("Some important data");

6。在你的活动中会有一个@Override 方法void sendData(String data);

@Override
public void sendData(String data) {
    Log.e("TAG", "sendData: this data is from Dialog " + data);
}

编辑1:解释

有 1 个 Activity A 和 1 个 DialogFragment B

B想向A发送数据

AB 一个interface 所以当B 调用dataTransfer.sendData("Hello");

A 也将调用它自己的overridden sendData(String data);

现在如果你打印这个

@Override
public void sendData(String data) {
    Log.e("TAG", "sendData: " + data);
}

这将打印出来

Hello

您可以从sendData 拨打任何其他method

希望这会有所帮助!

如果您需要更多帮助,请询问

【讨论】:

  • 这将如何执行方法getotherinformationbyaccountforprinting() ?这将在主要活动中填充文本视图
  • sendData中添加这个方法,并将数据作为参数传递
  • 你能详细说明你的答案吗?对不起,我是新手:(
  • 请查看我更新的答案,如果您需要其他相关的解释,请询问
【解决方案4】:

找到了关于如何从另一个类或片段中从 AutoCompletetextview 获取文本的答案

Inside Main Activity on Create 添加片段支持

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        ToPrintAccountSearchDialog toPrintAccountSearchDialog = new 
        ToPrintAccountSearchDialog();
        ToPrintNameSearchDialog toPrintNameSearchDialog = new ToPrintNameSearchDialog();
        fragmentTransaction.add(R.id.activity_print_bill,toPrintAccountSearchDialog);
        fragmentTransaction.commit();

然后在你的片段 onCreate 里面添加以下代码

            toprint_auto_account_search_dialog = 
            view.findViewById(R.id.Alert_Dialog_Account_Auto_Search);
            toprint_auto_account_search_dialog.setOnItemClickListener(new 
            AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
            {
                String account_no_to_print = 
                toprint_auto_account_search_dialog.getText().toString();
                PrintBill printBill = (PrintBill) getActivity();
                printBill.account_no_to_print(account_no_to_print);
                dismiss();
            }

然后在Main Activity里面创建一个变量,把autocompletetextview的值这样放

    public void account_no_to_print(String account_no)
    {
        this.ConsumerAccountForPrinting = account_no;
    }

【讨论】:

    猜你喜欢
    • 2011-10-01
    • 1970-01-01
    • 2019-04-24
    • 2014-05-20
    • 2015-05-07
    • 2011-04-07
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多