我必须开发一个Android应用程序,它对使用JSON字符串响应的服务器执行http GET请求。
因为我需要在应用中多次执行该请求,所以我创建了一个类,仅使用AsyncTask
执行此任务。
问题在于,我无法将JSON sting从AsyncTask
返回到活动并阅读一些问题我已经明白AsynkTask
不是&{39}。解决方案,所以我尝试使用Android服务执行请求,但我得到了NetworkOnMainThreadException
。
如何创建新线程来运行服务并将结果发送回活动?
答案 0 :(得分:0)
正如@ZygoteInit所述,在我看来,你应该使用AsyncTask
,你也可以用这种方式应用一些进度条。
但最简单的方法是使用Java本机线程和Android处理程序
final Handler handler = new Handler();
new Thread(new Runnable(){
@Override
public void run(){
final String json = fetchFromNetwork();
handler.post(new runnable(){
// finish callback (here is UI thread)
// do stuff with 'json' string
});
}
}).start();
答案 1 :(得分:0)
使用Volley.jar!它已经使用了asyncTask
private void makeJsonObjectRequest() {
showpDialog();
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.GET,
urlJsonObj, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
try {
// Parsing json object response
// response will be a json object
String name = response.getString("name");
String email = response.getString("email");
JSONObject phone = response.getJSONObject("phone");
String home = phone.getString("home");
String mobile = phone.getString("mobile");
jsonResponse = "";
jsonResponse += "Name: " + name + "\n\n";
jsonResponse += "Email: " + email + "\n\n";
jsonResponse += "Home: " + home + "\n\n";
jsonResponse += "Mobile: " + mobile + "\n\n";
txtResponse.setText(jsonResponse);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
hidepDialog();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
// hide the progress dialog
hidepDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq);
}
答案 2 :(得分:0)
您可以使用带有接口的线程:
线程类:
public class RequestTask extends Thread {
private ResultCallback callback;
public RequestTask(ResultCallback callback) {
this.callback = callback;
}
@Override
public void run() {
String result = "";
// (Your request)
callback.onFinished(result);
}
public interface ResultCallback {
public void onFinished(String data);
public void onError();
}
}
您需要数据的位置:
RequestTask task = new RequestTask(new ResultCallback() {
@Override
public void onFinished(String data) {
//do something
}
@Override
public void onError() {
//show an error
}
});
task.start();
答案 3 :(得分:0)
我喜欢使用groundy作为命令服务
public class LoginCommand extends GroundyTask{
private static final String ARG_PASSWORD = "arg_password";
private static final String ARG_USER = "arg_username";
@Override
protected TaskResult doInBackground() {
String userName = getStringArg(ARG_USER);
String password = getStringArg(ARG_PASSWORD);
//do something
return succeeded();
}
public static void start(Context context, BaseLoginCommandCallback callback, String login, String password) {
Groundy.create(LoginCommand.class)
.arg(ARG_USER, login)
.arg(ARG_PASSWORD, password)
.callback(callback)
.queueUsing(context);
}
public static abstract class BaseLoginCommandCallback{
@OnSuccess(LoginCommand.class)
public void handleSuccess(){
onLoginSuccess();
}
@OnFailure(LoginCommand.class)
public void handleFailure(){
onLoginError();
}
protected abstract void onLoginSuccess();
protected abstract void onLoginError();
}
}
或使用retrofit +gson─您可以使用groundy / AsyncTask / service + retrofit或使用异步请求改造
模型:
public class SignRequest {
private String login;
private String password;
public SignRequest(String login, String password) {
this.login = login;
this.password = password;
}
public SignRequest() {
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public class SignResponse implements Parcelable {
private long id;
private String login;
private String message;
@SerializedName("auth_token")
private String authToken;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getAuthToken() {
return authToken;
}
public void setAuthToken(String authToken) {
this.authToken = authToken;
}
public SignResponse() {
}
public SignResponse(Parcel in) {
this.id = in.readLong();
this.login = in.readString();
this.message = in.readString();
this.authToken = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeLong(id);
out.writeString(login);
out.writeString(message);
out.writeString(authToken);
}
}
API:
public interface Api {
public static final String URL = "http://xxxxxx/api/v1";
static final String AUTH_SIGNIN = "/auth/signin";
static final String AUTH_SIGNUP = "/auth/signup";
static final String QUERY_AUTH_TOKEN = "auth_token";
@POST(AUTH_SIGNIN)
void sign(@Body SignRequest request, Callback<SignResponse> callback);
@POST(AUTH_SIGNIN)
SignResponsesign(@Body SignRequest request);
@POST(AUTH_SIGNUP)
void signup(@Body SignUpRequest request, Callback<SignUpResponse> callback);
}
ASYNCHRONOUS:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auth);
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Api.URL)
.build();
Api api = restAdapter.create(Api.class);
SignRequest request= new SignRequest();
request.setLogin(login);
request.setPassword(password);
api.sign(request, new Callback<SignResponse>() {
@Override
public void success(SignResponse signResponse, Response response) {
Log.d("api", "login: " + signResponse.getLogin());
.......
}
@Override
public void failure(RetrofitError error) {
.....
});
}
SYNCHRONOUS(例如AsyncTask):
......
@Override
protected Void doInBackground(SignRequest... params) {
SignRequest request = params[0];
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Api.URL)
.build();
Api api = restAdapter.create(Api.class);
SignResponse response = api.sign(request);
return null;
}
.....