Return 到 activity 的 http 请求结果

Return http request result to an activity

我必须开发一个 Android 应用程序,它向服务器执行 http GET 请求,服务器响应 JSON 字符串。

因为我需要在应用程序中多次执行该请求,所以我创建了一个 class 仅用于使用 AsyncTask.

执行此任务

问题是我无法 return 从 AsyncTask 到 activity 的 JSON 并且阅读了一些我明白的问题AsynkTask 不是解决方案,所以我尝试使用 Android 服务执行请求,但我得到了 NetworkOnMainThreadException.

如何为 运行 服务创建一个新线程并将结果发送回 activity?

正如@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();

使用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);

}

Android JSON parsing using Volley

您可以使用带有接口的线程:

线程 class:

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();

我喜欢使用 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或者使用异步请求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);

} 

异步:

 @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) {
            .....
    });

}

同步(例如 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;
}

.....