将http请求结果返回给活动

时间:2015-03-01 18:30:28

标签: android android-asynctask android-service

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

因为我需要在应用中多次执行该请求,所以我创建了一个类,仅使用AsyncTask执行此任务。

问题在于,我无法将JSON sting从AsyncTask返回到活动并阅读一些问题我已经明白AsynkTask不是&{39}。解决方案,所以我尝试使用Android服务执行请求,但我得到了NetworkOnMainThreadException

如何创建新线程来运行服务并将结果发送回活动?

4 个答案:

答案 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);

}

Android JSON parsing using Volley

答案 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;
}

.....