尝试使用 volley 在远程数据库 mysql 上创建新记录时应用程序崩溃
app crashes when try to create new record on remote database mysql using volley
我创建了一个连接到远程 sql 数据库的简单 android 应用程序。问题是当我单击注册应用程序时崩溃。请大家帮帮我
package com.example.akshay.webservices;
/**
* Created by Akshay on 7/20/2015.
*/
import com.example.akshay.webservices.AppConfig;
import com.example.akshay.webservices.AppController;
import com.example.akshay.webservices.SQLiteHandler;
import com.example.akshay.webservices.SessionManager;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
public class RegisterActivity extends Activity {
private static final String TAG = RegisterActivity.class.getSimpleName();
private Button btnRegister;
private Button btnLinkToLogin;
private EditText inputFullName;
private EditText inputEmail;
private EditText inputPassword;
private ProgressDialog pDialog;
private SessionManager session;
private SQLiteHandler db;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
inputFullName = (EditText) findViewById(R.id.name);
inputEmail = (EditText) findViewById(R.id.email);
inputPassword = (EditText) findViewById(R.id.password);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
// Session manager
session = new SessionManager(getApplicationContext());
// SQLite database handler
db = new SQLiteHandler(getApplicationContext());
// Check if user is already logged in or not
if (session.isLoggedIn()) {
// User is already logged in. Take him to main activity
Intent intent = new Intent(RegisterActivity.this,
MainActivity.class);
startActivity(intent);
finish();
}
// Register Button Click event
btnRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String name = inputFullName.getText().toString();
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
registerUser(name, email, password);
} else {
Toast.makeText(getApplicationContext(),
"Please enter your details!", Toast.LENGTH_LONG)
.show();
}
}
});
// Link to Login Screen
btnLinkToLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),
LoginActivity.class);
startActivity(i);
finish();
}
});
}
/**
* Function to store user in MySQL database will post params(tag, name,
* email, password) to register url
* */
private void registerUser(final String name, final String email,
final String password) {
// Tag used to cancel the request
String tag_string_req = "req_register";
pDialog.setMessage("Registering ...");
showDialog();
StringRequest strReq = new StringRequest(Method.POST,
AppConfig.URL_REGISTER, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "Register Response: " + response.toString());
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
if (!error) {
// User successfully stored in MySQL
// Now store the user in sqlite
String uid = jObj.getString("uid");
JSONObject user = jObj.getJSONObject("user");
String name = user.getString("name");
String email = user.getString("email");
String created_at = user
.getString("created_at");
// Inserting row in users table
db.addUser(name, email, uid, created_at);
// Launch login activity
Intent intent = new Intent(
RegisterActivity.this,
LoginActivity.class);
startActivity(intent);
finish();
} else {
// Error occurred in registration. Get the error
// message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Registration Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
@Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "register");
params.put("name", name);
params.put("email", email);
params.put("password", password);
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
AppController.java
package com.example.akshay.webservices;
import android.app.Application;
/**
* Created by Akshay on 7/19/2015.
*/
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private static AppController mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
LogCat:
07-20 20:27:07.195 8233-8233/? E/Zygote﹕ MountEmulatedStorage()
07-20 20:27:07.195 8233-8233/? E/Zygote﹕ v2
07-20 20:27:07.195 8233-8233/? E/SELinux﹕ [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
07-20 20:27:18.355 8233-8233/com.example.akshay.webservices E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.akshay.webservices, PID: 8233
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.akshay.webservices.AppController.addToRequestQueue(com.android.volley.Request, java.lang.String)' on a null object reference
at com.example.akshay.webservices.RegisterActivity.registerUser(RegisterActivity.java:185)
at com.example.akshay.webservices.RegisterActivity.access0(RegisterActivity.java:32)
at com.example.akshay.webservices.RegisterActivity.onClick(RegisterActivity.java:81)
at android.view.View.performClick(View.java:5191)
at android.view.View$PerformClick.run(View.java:20916)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5972)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
这是 logcat 我无法理解发生了什么。请帮忙..
出现问题是因为 AppController.getInstance() 返回空值,
你必须改变你的 AppController.getInstance() 方法是这样的:
public static AppController getInstance() {
if (mInstance == null) {
mInstance = new AppController;
}
return mInstance;
}
还要确保您在清单中注册您的应用 class
你应该在你的清单应用程序中有一个这样的属性:
<application
android:name="package.AppController" <--------
android:allowBackup="true"
android:debuggable="true"
android:icon="@drawable/ic_launcher"
android:label="xyz"
android:screenOrientation="landscape"
android:theme="@style/AppTheme">
更多信息在这里:http://developer.android.com/reference/android/app/Application.html
"Base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's tag, which will cause that class to be instantiated for you when the process for your application/package is created. "
嘿,我遇到了同样的问题,当我尝试这个解决方案时它没有用,最后我找到了出路。
它返回空指针的问题是因为方法 getInstance() 和 getRequestQueue() 没有返回关于上下文的任何内容。要解决此问题,请按照以下步骤操作。作为先决条件,在 public class AppController extends Application private Context myContext.
下添加以下全局变量
第 1 步。
创建定义上下文的构造函数
public AppController(Context context){
myContext = context;
mRequestQueue = getRequestQueue();
}
第 2 步。修改 hyou getInstance() 方法以在上下文中工作,如下所示:
public static synchronized AppController getInstance(Context context) {
if(mInstance==null){
mInstance = new AppController(context);
}
return mInstance;
}
第 3 步。
最后修改 getRequestQueue() 方法以在上下文中工作,如下所示
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(myContext.getApplicationContext());
}
return mRequestQueue;
}
Finally got the calling class and call the methods from AppController.java with respect to the context of the activity or broadcaster.
AppController.getInstance(this).addToRequestQueue(strReq, tag_string_req);
我创建了一个连接到远程 sql 数据库的简单 android 应用程序。问题是当我单击注册应用程序时崩溃。请大家帮帮我
package com.example.akshay.webservices;
/**
* Created by Akshay on 7/20/2015.
*/
import com.example.akshay.webservices.AppConfig;
import com.example.akshay.webservices.AppController;
import com.example.akshay.webservices.SQLiteHandler;
import com.example.akshay.webservices.SessionManager;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
public class RegisterActivity extends Activity {
private static final String TAG = RegisterActivity.class.getSimpleName();
private Button btnRegister;
private Button btnLinkToLogin;
private EditText inputFullName;
private EditText inputEmail;
private EditText inputPassword;
private ProgressDialog pDialog;
private SessionManager session;
private SQLiteHandler db;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
inputFullName = (EditText) findViewById(R.id.name);
inputEmail = (EditText) findViewById(R.id.email);
inputPassword = (EditText) findViewById(R.id.password);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
// Session manager
session = new SessionManager(getApplicationContext());
// SQLite database handler
db = new SQLiteHandler(getApplicationContext());
// Check if user is already logged in or not
if (session.isLoggedIn()) {
// User is already logged in. Take him to main activity
Intent intent = new Intent(RegisterActivity.this,
MainActivity.class);
startActivity(intent);
finish();
}
// Register Button Click event
btnRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String name = inputFullName.getText().toString();
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
registerUser(name, email, password);
} else {
Toast.makeText(getApplicationContext(),
"Please enter your details!", Toast.LENGTH_LONG)
.show();
}
}
});
// Link to Login Screen
btnLinkToLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),
LoginActivity.class);
startActivity(i);
finish();
}
});
}
/**
* Function to store user in MySQL database will post params(tag, name,
* email, password) to register url
* */
private void registerUser(final String name, final String email,
final String password) {
// Tag used to cancel the request
String tag_string_req = "req_register";
pDialog.setMessage("Registering ...");
showDialog();
StringRequest strReq = new StringRequest(Method.POST,
AppConfig.URL_REGISTER, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "Register Response: " + response.toString());
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
if (!error) {
// User successfully stored in MySQL
// Now store the user in sqlite
String uid = jObj.getString("uid");
JSONObject user = jObj.getJSONObject("user");
String name = user.getString("name");
String email = user.getString("email");
String created_at = user
.getString("created_at");
// Inserting row in users table
db.addUser(name, email, uid, created_at);
// Launch login activity
Intent intent = new Intent(
RegisterActivity.this,
LoginActivity.class);
startActivity(intent);
finish();
} else {
// Error occurred in registration. Get the error
// message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Registration Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
@Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "register");
params.put("name", name);
params.put("email", email);
params.put("password", password);
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
AppController.java
package com.example.akshay.webservices;
import android.app.Application;
/**
* Created by Akshay on 7/19/2015.
*/
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private static AppController mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
LogCat:
07-20 20:27:07.195 8233-8233/? E/Zygote﹕ MountEmulatedStorage()
07-20 20:27:07.195 8233-8233/? E/Zygote﹕ v2
07-20 20:27:07.195 8233-8233/? E/SELinux﹕ [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
07-20 20:27:18.355 8233-8233/com.example.akshay.webservices E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.akshay.webservices, PID: 8233
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.akshay.webservices.AppController.addToRequestQueue(com.android.volley.Request, java.lang.String)' on a null object reference
at com.example.akshay.webservices.RegisterActivity.registerUser(RegisterActivity.java:185)
at com.example.akshay.webservices.RegisterActivity.access0(RegisterActivity.java:32)
at com.example.akshay.webservices.RegisterActivity.onClick(RegisterActivity.java:81)
at android.view.View.performClick(View.java:5191)
at android.view.View$PerformClick.run(View.java:20916)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5972)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
这是 logcat 我无法理解发生了什么。请帮忙..
出现问题是因为 AppController.getInstance() 返回空值, 你必须改变你的 AppController.getInstance() 方法是这样的:
public static AppController getInstance() {
if (mInstance == null) {
mInstance = new AppController;
}
return mInstance;
}
还要确保您在清单中注册您的应用 class 你应该在你的清单应用程序中有一个这样的属性:
<application
android:name="package.AppController" <--------
android:allowBackup="true"
android:debuggable="true"
android:icon="@drawable/ic_launcher"
android:label="xyz"
android:screenOrientation="landscape"
android:theme="@style/AppTheme">
更多信息在这里:http://developer.android.com/reference/android/app/Application.html
"Base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's tag, which will cause that class to be instantiated for you when the process for your application/package is created. "
嘿,我遇到了同样的问题,当我尝试这个解决方案时它没有用,最后我找到了出路。
它返回空指针的问题是因为方法 getInstance() 和 getRequestQueue() 没有返回关于上下文的任何内容。要解决此问题,请按照以下步骤操作。作为先决条件,在 public class AppController extends Application private Context myContext.
下添加以下全局变量第 1 步。 创建定义上下文的构造函数
public AppController(Context context){
myContext = context;
mRequestQueue = getRequestQueue();
}
第 2 步。修改 hyou getInstance() 方法以在上下文中工作,如下所示:
public static synchronized AppController getInstance(Context context) {
if(mInstance==null){
mInstance = new AppController(context);
}
return mInstance;
}
第 3 步。 最后修改 getRequestQueue() 方法以在上下文中工作,如下所示
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(myContext.getApplicationContext());
}
return mRequestQueue;
}
Finally got the calling class and call the methods from AppController.java with respect to the context of the activity or broadcaster.
AppController.getInstance(this).addToRequestQueue(strReq, tag_string_req);