现在,我使用android studio和本机java制作的应用程序已经完成。 然后我将其更改为APK以上传到Play商店。
应用程序以启动屏幕启动,然后将其定向到登录页面 如果SharedPreference中不存在jwt。
下面是MainActivity.java作为初始屏幕UI。
public class MainActivity extends AppCompatActivity {
int loadingTime = 2000;
final Context context = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "Client Warehouse Dzil");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
SharedPreferences preferences = getSharedPreferences("session",Context.MODE_PRIVATE);
final String token = preferences.getString("token", null);
if (token != null) { // check, if jwt is Exist take to home
Intent home = new Intent(MainActivity.this, HomeActivity.class);
startActivity(home);
} else { // other, display login page
Intent login = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(login);
}
finish();
}
}, loadingTime);
}
}
问题是当我从此应用程序生成APK时。 调试版本没有问题,但是发行版本有问题。 甚至是我将上传到Play商店的该版本。 这是LoginActivity
package com.tsurumaru.dzil.clientwarehouse.activity.login;
import com.tsurumaru.dzil.clientwarehouse.R;
import com.tsurumaru.dzil.clientwarehouse.activity.home.HomeActivity;
import com.tsurumaru.dzil.clientwarehouse.model.LoginRestModel;
import com.tsurumaru.dzil.clientwarehouse.remote.LoginRestService;
import com.tsurumaru.dzil.clientwarehouse.remote.RestApiUtils;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* A login screen that offers login via email/password.
*/
public class LoginActivity extends AppCompatActivity {
EditText edtUsername;
EditText edtPassword;
Button btnLogin;
ProgressBar progressBar;
LoginRestService loginRestService;
@Override
protected void onStart() {
super.onStart();
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(new String[]{
Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 2);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
edtUsername = findViewById(R.id.edtUsername);
edtPassword = findViewById(R.id.edtPassword);
btnLogin = findViewById(R.id.btnLogin);
progressBar = findViewById(R.id.progressBar);
loginRestService = RestApiUtils.getLoginRestService();
btnLogin.setOnClickListener(view -> {
String username = edtUsername.getText().toString();
String password = edtPassword.getText().toString();
//validate the form
if (validateLogin(username, password)) {
doLogin(username, password);
progressBar.setVisibility(View.VISIBLE);
}
});
}
private boolean validateLogin(String username, String password) {
if (username == null || username.trim().length() == 0) {
Toast.makeText(this, "Username is required", Toast.LENGTH_SHORT).show();
return false;
}
if (password == null || password.trim().length() == 0) {
Toast.makeText(this, "Password is required", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
private void doLogin(String username, String password) {
Call<LoginRestModel> call = loginRestService.auth(username, password);
call.enqueue(new Callback<LoginRestModel>() {
@Override
public void onResponse(Call<LoginRestModel> call, Response<LoginRestModel> response) {
if (response.isSuccessful()) {
LoginRestModel resObj = response.body();
if (resObj.getStatus().equals("success")) {
/* Save to sharedPreferences*/
saveSession(resObj.getId(), resObj.getUsername(), resObj.getToken());
// Redirect to Home Page
Intent intent = new Intent(LoginActivity.this, HomeActivity.class);
startActivity(intent);
} else {
Toast.makeText(LoginActivity.this, "The username and password is incorrect", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(LoginActivity.this, "Error, please try again", Toast.LENGTH_SHORT).show();
}
progressBar.setVisibility(View.INVISIBLE);
}
@Override
public void onFailure(Call<LoginRestModel> call, Throwable t) {
Toast.makeText(LoginActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
call.cancel();
}
});
}
public void saveSession(int id, String username, String token) {
SharedPreferences sharedPreferences = getSharedPreferences("session", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("id", id);
editor.putString("username", username);
editor.putString("token", token);
editor.apply();
}
}
在APK调试中,如上所述的Retrofit调用中的doLogin函数成功运行。 在APK Release中,该应用突然关闭并重新启动。我在Logcat中看到了:
Process: com.tsurumaru.dzil.clientwarehouse, PID: 31649
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at c.h.a.a.a.c.b.a(:4)
at g.i.run()
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
06-17 19:15:45.444 960-1190/? E/InputDispatcher: channel
'248fd78b com.tsurumaru.dzil.clientwarehouse/com.tsurumaru.dzil.clientwarehouse.activity.login.LoginActivity (server)'
~ Channel is unrecoverably broken and will be disposed!
在c.h.a.a.a.c.b.a中说为空??? 这是什么,它非常感谢您的帮助。
答案 0 :(得分:1)
发布模式缩小并缩小了项目。结果,您必须实现proguard或将minify and shrinking设置为false
buildTypes {
release {
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
,还有at c.h.a.a.a.c.b.a
被混淆。由于 proguard 弱,这是不必要的混淆。