Android 带有 ProgressDialog 的 AsyncTask - 空对象引用

Android AsyncTask with ProgressDialog - Null object reference

我的 Android 应用程序中有一个 AsyncTask class。我的 MainActivity 调用了其中的一个方法 class,但是当我这样做时,其中的 ProgressDialog 框出现问题。

这是我收到的错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference
at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:222)
at android.app.AlertDialog.<init>(AlertDialog.java:200)
at android.app.AlertDialog.<init>(AlertDialog.java:196)
at android.app.AlertDialog.<init>(AlertDialog.java:141)
at android.app.ProgressDialog.<init>(ProgressDialog.java:77)
at com.example.maindec.sme.LoginSoapTask.<init>(LoginSoapTask.java:30)
at com.example.maindec.sme.MainActivity.onClick(MainActivity.java:103)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

以下是 classes 中代码的主要部分:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private String username;
    private String password;

    private EditText usernameField;
    private EditText passwordField;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        usernameField = (EditText) findViewById(R.id.enterUsername);
        passwordField = (EditText) findViewById(R.id.enterPassword);

        passwordField.setTypeface(Typeface.DEFAULT);
        passwordField.setTransformationMethod(new PasswordTransformationMethod());


        loginButton.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {

                    LoginSoapTask lert = new LoginSoapTask(getApplicationContext()); //THIS IS WHERE I'M HAVING THE PROBLEM (Line 103)
                   // lert.checkDetails(usernameField.getText().toString(), passwordField.getText().toString());
                }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

LoginSoapTask.java

public class LoginSoapTask extends AsyncTask<Void, Void, Void> {
    /*Web Service Details */

    private String xmlProlog = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

    public String username, password;

    Context context;
    public LoginSoapTask(Context c) {
        context = c;
    }
    private final ProgressDialog dialog = new ProgressDialog(context); //THIS IS WHERE I AM HAVING THE PROBLEM!!!!!!!!! (Line 30)
    protected void onPreExecute() {

        this.dialog.setMessage("Verifying...");
        dialog.show();
    }


    @Override
    protected Void doInBackground(Void... params) {
        return null;
    }

    protected void onPostExecute(Void result) {
        // TextView tv = (TextView) findViewById(R.id.Result);
        //  tv.setText(test_string);
        System.out.println(test_string);
        if (this.dialog.isShowing()){
            this.dialog.dismiss();
         }
    }

    private String test_string;

    @SuppressWarnings("deprecation")
    public void WebServiceCallExample() {
        String finalInput = "1:" + username.length() + ":" + username + ":2:" + password.length() + ":" + password + ":";
        SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
        Request.addProperty("credentials", finalInput);

        /* Set the web service envelope */
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(Request);
        System.out.println("Request::" + Request.toString());

        HttpTransportSE httpTransport = new HttpTransportSE(URL);
        try{
            System.out.println("Lghung:" + SOAP_ACTION);
            httpTransport.debug=true;

            httpTransport.call(SOAP_ACTION, envelope);
            String ss=httpTransport.responseDump;
            //SoapObject sp = (SoapObject) envelope.getResponse();
             SoapPrimitive response = (SoapPrimitive) envelope.getResponse();

            SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
            System.out.println("Response::" + resultsRequestSOAP.toString());
            System.out.println(Request.getName());
             test_string = xmlProlog + response.toString();
             System.out.println(test_string);
        }catch (Exception e){
            System.out.println("Testing");
            e.printStackTrace();
        }

    }

    public void checkDetails(String givenUsername, String givenPassword) {
        username = givenUsername;
        password = givenPassword;
        execute();
    }
}

我插入了引号,说 "THIS IS WHERE I AM HAVING THE PROBLEM",给你一个先机。

如果您知道如何解决这个问题,不要post链接其他解决方案。 Post 一个可以直接解决这个问题的代码答案。我已经查看了与上下文有关的其他解决方案,但我一无所获。

而不是

LoginSoapTask lert = new LoginSoapTask(getApplicationContext());

试试这个

LoginSoapTask lert = new LoginSoapTask(MainActivity.this);

在 MainActivity 中

替换

LoginSoapTask lert = new LoginSoapTask(getApplicationContext()); 

LoginSoapTask lert = new LoginSoapTask(MainActivity.this); 

稍微更改构造函数以在其中创建对话框。

Context context;
private final ProgressDialog dialog;

public LoginSoapTask(Context c) {
    context = c;
    dialog = new ProgressDialog(context);
}

此外,您可能会发现在 clickListener 中使用视图 (v) 参数的上下文更容易,这里是一个示例:

loginButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        LoginSoapTask lert = new LoginSoapTask(v.getContext());
        // lert.checkDetails(usernameField.getText().toString(), passwordField.getText().toString());
    }
});

原来我创建了 MainActivity 的 public 实例并将其传输到 LoginSoapTask。与你们设置的方式略有不同。我将其用作不同的 public 方法。