简体   繁体   English

尝试从另一个类调用方法时出现空指针异常?

[英]Null pointer exception when trying to invoke the method from another class?

Currently getting a nullpointer exception when attempting to validate a User's credentials, I believe it's being caused in the OnPostExecute method, but I cannot figure out what's causing it. 目前,在尝试验证用户的凭据时会收到nullpointer异常,我认为这是在OnPostExecute方法中引起的,但我无法弄清楚是什么原因引起的。 Here is my BackgroundWorker class, as well as my LoginActivity. 这是我的BackgroundWorker类以及LoginActivity。 The PHP file for login return either "LoginSuccess", or "LoginFailed". 用于登录的PHP文件返回“ LoginSuccess”或“ LoginFailed”。 The error seems to be happening when OnPostExecute is trying to invoke the methods from the Login Activity, any idea of how to fix this? 当OnPostExecute尝试从Login Activity调用方法时,似乎发生了错误,是否有解决方法?

public class BackgroundWorker extends AsyncTask<String, Void, String>{
Context context;
AlertDialog alertDialog;
LoginActivity loginActivity;
BackgroundWorker (Context ctx) {
    context = ctx;
}
@Override
protected String doInBackground(String... params) {
    String type = params[0];

if(type.equals("login")) {
        //If a registered user is trying to login
        try {
            String username = params[1];
            String password = params[2];
            URL url = new URL(login_url);
            HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            OutputStream outputStream = httpURLConnection.getOutputStream();
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
            String post_data = URLEncoder.encode("username", "UTF-8")+"="+URLEncoder.encode(username, "UTF-8")+"&"
                    +URLEncoder.encode("password", "UTF-8")+"="+URLEncoder.encode(password, "UTF-8");
            bufferedWriter.write(post_data);
            bufferedWriter.flush();
            bufferedWriter.close();
            outputStream.close();
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
            String result="";
            String line="";
            while((line = bufferedReader.readLine()) != null) {
                result+=line;
            }
            bufferedReader.close();
            inputStream.close();
            httpURLConnection.disconnect();
            return result;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    } else if(type.equals("register")) {
        //If a new user to trying to register
        try {
            String str_name = params[1];
            String str_username = params[2];
            String str_password = params[3];
            String str_email = params[4];
            URL url = new URL(register_url);
            HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            OutputStream outputStream = httpURLConnection.getOutputStream();
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
            String post_data = URLEncoder.encode("name", "UTF-8")+"="+URLEncoder.encode(str_name, "UTF-8")+"&"+
                    URLEncoder.encode("user_name", "UTF-8")+"="+URLEncoder.encode(str_username, "UTF-8")+"&"
                    +URLEncoder.encode("user_pass", "UTF-8")+"="+URLEncoder.encode(str_password, "UTF-8")
                    +"&"+URLEncoder.encode("user_email", "UTF-8")+"="+URLEncoder.encode(str_email, "UTF-8");
            bufferedWriter.write(post_data);
            bufferedWriter.flush();
            bufferedWriter.close();
            outputStream.close();
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
            String result="";
            String line="";
            while((line = bufferedReader.readLine()) != null) {
                result+=line;
            }
            bufferedReader.close();
            inputStream.close();
            httpURLConnection.disconnect();
            return result;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    return null;
}
@Override
protected void onPreExecute() {
    alertDialog = new AlertDialog.Builder(context).create();
    alertDialog.setTitle("Login Status");
}

@Override
protected void onPostExecute(String result) {
    switch(result){
        case "LoginSuccess":
            loginActivity.OnLoginSuccess();
            break;
        case "LoginFailed":
            loginActivity.OnLoginFailed();
            break;

    }
}

@Override
protected void onProgressUpdate(Void... values) {
    super.onProgressUpdate(values);
    }
}

LoginActivity 登录活动

public class LoginActivity extends AppCompatActivity{
EditText etUsername, etPassword;
Button bLogin;
String tmpUsername;




@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    etUsername = (EditText) findViewById(R.id.etUsername);
    etPassword = (EditText) findViewById(R.id.etPassword);
    bLogin = (Button) findViewById(R.id.bLogin);
    final TextView registerLink = (TextView) findViewById(R.id.tvRegisterHere);
    tmpUsername = "";

    requestPermissions();

}

@RequiresApi(api = Build.VERSION_CODES.M)
private boolean requestPermissions() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.INTERNET
        }, 1 );
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return true;
    } else {
        return false;
    }

}


public void OnLogin(View view){
    String username = etUsername.getText().toString();
    String password = etPassword.getText().toString();
    String type = "login";
    tmpUsername = username;
    BackgroundWorker loginRequest = new BackgroundWorker(this);
    loginRequest.execute(type, username, password);

}
public void OpenReg(View view) {
    startActivity(new Intent(this, RegisterActivity.class));
}


public void OnLoginSuccess(){
    Intent intent = new Intent(LoginActivity.this, ViewGroupActivity.class);
    intent.putExtra("username", tmpUsername);
    startActivity(intent);

}

public void OnLoginFailed(){
    Toast.makeText(this, "Username or password doesn't match.  Please try again",Toast.LENGTH_SHORT).show();
}

Here is my logcat 这是我的日志

04-04 15:02:11.180 6775-6775/com.example.myproject.findme E/AndroidRuntime: 
FATAL EXCEPTION: main
Process: com.example.myproject.findme, PID: 6775
java.lang.NullPointerException: Attempt to invoke virtual method 
'java.lang.String android.content.Context.getPackageName()' on a null object 
reference
    at android.content.ContextWrapper.getPackageName(ContextWrapper.java:135)
    at android.widget.Toast.<init>(Toast.java:114)
    at android.widget.Toast.makeText(Toast.java:277)
    at android.widget.Toast.makeText(Toast.java:267)
    at com.example.myproject.findme.LoginActivity.OnLoginFailed(LoginActivity.java:97)
    at com.example.myproject.findme.BackgroundWorker.onPostExecute(BackgroundWorker.java:288)
    at com.example.myproject.findme.BackgroundWorker.onPostExecute(BackgroundWorker.java:25)
    at android.os.AsyncTask.finish(AsyncTask.java:695)
    at android.os.AsyncTask.-wrap1(Unknown Source:0)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

As I noticed you did not initialize your loginActivity instance variable. 我注意到您没有初始化loginActivity实例变量。 You can do that witb setter method or in constructor of your BackgroundWorker class. 您可以使用witb setter方法或在BackgroundWorker类的构造函数中进行操作。 Currently you are passing only the reference of Context object. 当前,您仅传递Context对象的引用。 You should write you BackgroundWorker constructor like this 您应该像这样编写BackgroundWorker构造函数

BackgroundWorker(LoginActivity  loginActivity){
     this.loginActivity = loginActivity;
}  

and in login activity pass param - this - like that 并在登录活动中传递参数-这样-这样

new BackgroundWorker(this)

and you also can use the loginActivity reference as a context in your BackgroundWorker. 并且您还可以将loginActivity引用用作BackgroundWorker中的上下文。

it will work 100%. 它将100%工作。

but it will be better if you will use interface methods as callback. 但是如果将接口方法用作回调会更好。

for example: 例如:

interface BackgroundWorkerCallback{
      Contrxt getContext();
      void success();
      void failed();
}  

implement this interface in your LoginActivity override last two methods as you would like and the first one should return context reference. 在您的LoginActivity中实现此接口,请根据需要覆盖后两种方法,第一种应返回上下文引用。

in you BackgroundWorker class 在您的BackgroundWorker类中

change the constructor like this: 像这样更改构造函数:

 private BackgroundWorkerCallback    callback;
 public  BackgroundWorker(BackgroundWorkerCallback callback){
         this.callback = callback;
 }

and in your post execute method call methods like this 并在您的后执行方法调用方法像这样

if success callback.success();
else if failed callback.failed();

and for context use 和用于上下文

callback.getContext();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM