java - 通过 AlertDialog 关闭并稍后重新打开时 Activity 崩溃

标签 java android android-activity android-alertdialog

一切都按预期进行,直到我使用 AlertDialog 按钮退出 Activity 并通过主菜单重新进入相​​同的对话框。

以下是我对 AlertDialog 进行编码的方式:

        AlertDialog.Builder builder = new AlertDialog.Builder(NewCustomerInfoActivity.this);
        if (result.equals("{\"success\":true}")){
            builder.setMessage("Yeni müşteri başarıyla kaydedildi.").setTitle("Kayıt Başarılı");
            builder.setPositiveButton("Ana ekrana dön", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    Intent backToMainActivityIntent = new Intent(NewCustomerInfoActivity.this, MainActivity.class);
                    dialog.dismiss();
                    startActivity(backToMainActivityIntent);
                }
            });
        } else {
            builder.setMessage("Yeni müşteri kaydedilemedi.").setTitle("Kayıt Başarısız");
            builder.setPositiveButton("Tamam", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });
        }
        AlertDialog dialog = builder.create();
        dialog.show();

如果我删除上面的代码,一切都会正常。

整个 Activity (如果有帮助):

public class NewCustomerInfoActivity extends AppCompatActivity {
String jCities;
ArrayList<City> cities;
ArrayList<String> cityStrings;
ArrayList<String> townStrings;
RadioButton personalRadioButton;
RadioButton corporateRadioButton;
Spinner citySpinner;
Spinner townSpinner;
String url;
int isPersComp = 1;
String cityString = "Adana";
int cityNo = 1;
String townString = "Aladağ";
int townNo = 1;
JSONObject json;
String deviceId;
User user;
String result;
Toast toast;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_customer_info);
    deviceId = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
    user = (User) getIntent().getSerializableExtra("user");
    url = getResources().getString(R.string.service_call_url) + "newCustomer/" + deviceId + "/" + user.getSecureSessionId() + "/";

    // Kayıtlı şehir ve ilçeler okunur.
    SharedPreferences prefs = getSharedPreferences("cities", MODE_PRIVATE);
    jCities = prefs.getString("jCities", null);
    if (!(jCities.isEmpty() || jCities == null)){
        WebRequest webRequest = new WebRequest();
        cities = webRequest.parseCities(jCities);
        cityStrings = new ArrayList<String>();
        for (City city : cities){
            if (!cityStrings.contains(city.getCityName())){
                cityStrings.add(city.getCityName());
            }
        }
    }

    // Tüzel - Şahıs radio butonlarının kendilerine dokunulması durumunda tepkileri belirlenir.
    personalRadioButton = (RadioButton) findViewById(R.id.personalRadioButton);
    corporateRadioButton = (RadioButton) findViewById(R.id.corporateRadioButton);
    isPersComp = 1;
    View.OnClickListener optionOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            TextView taxOrIdNoTitleTextView = (TextView) findViewById(R.id.taxOrIdNoTitleTextView);

            if (personalRadioButton.isChecked()){
                taxOrIdNoTitleTextView.setText("TC Kimlik No:");
                isPersComp = 1;
            }
            if (corporateRadioButton.isChecked()){
                taxOrIdNoTitleTextView.setText("Vergi No:");
                isPersComp = 0;
            }
        }
    };
    personalRadioButton.setOnClickListener(optionOnClickListener);
    corporateRadioButton.setOnClickListener(optionOnClickListener);

    // İl seçimi için spinner doldurulur.
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, cityStrings);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    final Spinner citySpinner = (Spinner) findViewById(R.id.citySpinner);
    citySpinner.setAdapter(adapter);
    citySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            cityString = citySpinner.getSelectedItem().toString();
            cityNo = 1 + citySpinner.getSelectedItemPosition();
            resetTownSpinner(cityNo);
        }
        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {
        }
    });
}

// Şehir seçimi yapılınca çağırılan ve ilçe spinner'ını seçilen şehre göre dolduran fonksiyon.
public void resetTownSpinner(int cityCode){
    townStrings = new ArrayList<String>();
    for (City city : cities){
        if (city.getCityCode() == cityCode){
            townStrings.add(city.getTownName());
        }
    }
    townSpinner = (Spinner) findViewById(R.id.townSpinner);
    ArrayAdapter<String> townAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, townStrings);
    townSpinner.setAdapter(townAdapter);
    townSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            townString = townSpinner.getSelectedItem().toString();
            townNo = 1 + townSpinner.getSelectedItemPosition();
        }
        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {
        }
    });
}

// Kayıt butonuna basıldığında çağırılan fonksiyon.
public void saveNewCustomer (View view){

    // JSON objesi oluşturulur.
    json = new JSONObject();
    try {
        // JSON objesi kullanıcının girdiği değerlere göre doldurulur.
        JSONObject jCustomer = new JSONObject();
        jCustomer.put("LOGICALREF", 0);
        jCustomer.put("CODE", "");
        EditText definitionText = (EditText) findViewById(R.id.definitionText);
        jCustomer.put("DEFINITION_", definitionText.getText().toString());
        jCustomer.put("ISPERSCOMP", isPersComp);
        EditText taxOrIdNoText = (EditText) findViewById(R.id.taxOrIdNoText);
        if (isPersComp == 1){
            jCustomer.put("TAXNR", "");
            jCustomer.put("TCKNO", taxOrIdNoText.getText().toString());
        } else {
            jCustomer.put("TAXNR", taxOrIdNoText.getText().toString());
            jCustomer.put("TCKNO", "");
        }
        EditText taxOfficeText = (EditText) findViewById(R.id.taxOfficeText);
        String taxOfficeString = taxOfficeText.getText().toString();
        if (taxOfficeString.isEmpty() || taxOfficeString == null){
            jCustomer.put("TAXOFFICE", "TCKIMLIK");
        } else {
            jCustomer.put("TAXOFFICE", taxOfficeString);
        }
        EditText emailText = (EditText) findViewById(R.id.emailText);
        jCustomer.put("EMAILADDR", emailText.getText().toString());
        EditText address1Text = (EditText) findViewById(R.id.address1Text);
        jCustomer.put("ADDR1", address1Text.getText().toString());
        EditText address2Text = (EditText) findViewById(R.id.address2Text);
        jCustomer.put("ADDR2", address2Text.getText().toString());
        jCustomer.put("CITY", cityString);
        jCustomer.put("CITYCODE", cityNo);
        jCustomer.put("TOWN", townString);
        jCustomer.put("TOWNCODE", townNo);
        EditText inChargeText = (EditText) findViewById(R.id.inChargeText);
        jCustomer.put("INCHARGE", inChargeText.getText().toString());
        EditText nameText = (EditText) findViewById(R.id.nameText);
        jCustomer.put("NAME", nameText.getText().toString());
        EditText surnameText = (EditText) findViewById(R.id.surnameText);
        jCustomer.put("SURNAME", surnameText.getText().toString());
        EditText phoneNo1Text = (EditText) findViewById(R.id.phoneNo1Text);
        jCustomer.put("TELNRS1", phoneNo1Text.getText().toString());
        EditText phoneNo2Text = (EditText) findViewById(R.id.phoneNo2Text);
        jCustomer.put("TELNRS2", phoneNo2Text.getText().toString());
        json.put("data", jCustomer);

        // JSON objesini server'a gönderen Thread başlatılır.
        new postJSON().execute();
    } catch (Exception e){
        e.printStackTrace();
    }
}

// JSON objesini server'a gönderen Thread.
private class postJSON extends AsyncTask<Void, Void, Void>{
    ProgressDialog progressDialog;

    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog = new ProgressDialog(NewCustomerInfoActivity.this);
        progressDialog.setMessage("Yeni müşteri kaydediliyor. Lütfen bekleyiniz.");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        WebRequest webRequest = new WebRequest();
        // JSON objesi string'e dönüştürülür ve linkin sonuna eklenir.
        url = url + json.toString();
        result = webRequest.getJson(url, true);
        return null;
    }

    protected void onPostExecute(Void requestResult) {
        super.onPostExecute(requestResult);
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(NewCustomerInfoActivity.this);
        // Server'dan dönen değer kontrol edilir.
        if (result.equals("{\"success\":true}")){
            builder.setMessage("Yeni müşteri başarıyla kaydedildi.").setTitle("Kayıt Başarılı");
            builder.setPositiveButton("Ana ekrana dön", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    Intent backToMainActivityIntent = new Intent(NewCustomerInfoActivity.this, MainActivity.class);
                    dialog.dismiss();
                    startActivity(backToMainActivityIntent);
                }
            });
        } else {
            builder.setMessage("Yeni müşteri kaydedilemedi.").setTitle("Kayıt Başarısız");
            builder.setPositiveButton("Tamam", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });
        }
        AlertDialog dialog = builder.create();
        dialog.show();
    }
}
}

同样,只要不使用 AlertDialog 就没有问题。完全没问题,除非您使用 AlertDialog 然后尝试再次进入 Activity,然后应用程序就会停止工作。

Logcat:

07-27 13:14:16.113 28618-28618/eof.concrete E/AndroidRuntime: FATAL EXCEPTION: main
                                                              Process: eof.concrete, PID: 28618
                                                              java.lang.RuntimeException: Unable to start activity ComponentInfo{eof.concrete/eof.concrete.newCustomer.NewCustomerInfoActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String eof.concrete.classes.User.getSecureSessionId()' on a null object reference
                                                                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
                                                                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
                                                                  at android.app.ActivityThread.-wrap11(Unknown Source:0)
                                                                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
                                                                  at android.os.Handler.dispatchMessage(Handler.java:105)
                                                                  at android.os.Looper.loop(Looper.java:164)
                                                                  at android.app.ActivityThread.main(ActivityThread.java:6540)
                                                                  at java.lang.reflect.Method.invoke(Native Method)
                                                                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
                                                               Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String eof.concrete.classes.User.getSecureSessionId()' on a null object reference
                                                                  at eof.concrete.newCustomer.NewCustomerInfoActivity.onCreate(NewCustomerInfoActivity.java:64)
                                                                  at android.app.Activity.performCreate(Activity.java:6980)
                                                                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
                                                                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
                                                                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
                                                                  at android.app.ActivityThread.-wrap11(Unknown Source:0) 
                                                                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
                                                                  at android.os.Handler.dispatchMessage(Handler.java:105) 
                                                                  at android.os.Looper.loop(Looper.java:164) 
                                                                  at android.app.ActivityThread.main(ActivityThread.java:6540) 
                                                                  at java.lang.reflect.Method.invoke(Native Method) 
                                                                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

最佳答案

问题出在这一行,而不是在AlertDialog

user = (User) getIntent().getSerializableExtra("user");

在调用 getIntent() 之前,您需要确保您的 Activity 已由 Intent 创建。 当您的 Activity 被 Android 框架销毁并重新创建时,Intent 将为 null。

如果 Intent 中的用户对象是 Activity 功能的基础,那么您可以完成它。

Intent intent = getIntent();
if (intent != null){
    user = (User) intent.getSerializableExtra("user");
    if (user == null){
        //handle null user
    }
} else {
    //here you can call finish() if the user is fundamental to your Activity
    //or you must handle a possible nullable `User` object in the following code
    finish();
    return;
}

在您的 AlertDialog 中,如果您想简单地返回到上一个 Activity,您可以替换此代码

Intent backToMainActivityIntent = new Intent(NewCustomerInfoActivity.this,
             MainActivity.class);
dialog.dismiss();
startActivity(backToMainActivityIntent);

有了这个

dialog.dismiss();
finish();

关于java - 通过 AlertDialog 关闭并稍后重新打开时 Activity 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45351340/

相关文章:

android - 在 Android 应用程序的 Web View 上显示网页时出错

android - 我应该在哪里全局保存/缓存所有应用程序生命周期所需的数据?

android - 更改微调器下拉图标

java - 为什么函数不从android中的php获取数据?

android - 将 Fragment 中的 Parcelable 对象共享到 Activity

javascript - 使用 Ionic Framework 点击/单击无法在移动设备上运行的选择元素

Java stream collect to map with multiple keys

javamail在企业中使用outlook

java - 验证以检查其是否为 ".txt"文件

java - Spring MVC : @Value annotation to get int value defined in *. 属性文件