【问题标题】:Creating a Network Thread as a Method创建网络线程作为方法
【发布时间】:2016-05-10 09:25:21
【问题描述】:

我是 Android 编程新手 - 请多多包涵。

我正在使用 OKHttp 构建一个需要网络访问的应用程序。由于我将从我的服务器发出许多类似结构的请求,因此我创建了一个类来处理所有与网络相关的任务,因为我喜欢将事情分开。

我正在研究的一种方法是 createNetworkThread 来自我的 NetworkManager 类。这个特殊的方法需要三个参数:

Context context, final String requestURI, final RequestBody formParameters

我需要帮助的是如何返回从该方法接收到的数据,以便我可以在调用 Activity 时使用和操作它。

这里是有问题的方法:

public void createNetworkThread(Context context, final String requestURI, final RequestBody formParameters) {
    if (!this.isConnected(context)) return;

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().url(requestURI).post(formParameters).build();

            Response response = null;

            // Send login request, get response //

            try {
                response = client.newCall(request).execute();
                String stringResponse = response.body().string();
                JSONObject jsonResponse = new JSONObject(stringResponse);

                Log.d("Net", "Request send and received!");

            } catch (IOException e) {
                Log.d("Net", "Failed");
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    };

    Thread thread = new Thread(runnable);
    thread.start();
}

这是来自 Activity 的调用:

final NetworkManager Net = new NetworkManager(this);

...

final String requestURI = "http://192.168.1.111/videonow.club/apprequest/signup/thread.php";
final RequestBody formVars = new FormBody.Builder().add("email", strEmail).add("password", strPass1).add("first_name", strNameFirst).add("last_name", strNameLast).build();

Net.createNetworkThread(SignupActivity.this, requestURI, formVars);

我需要知道的是如何从方法返回的jsonResponse 中获取JSON 数据(我知道void 不允许这样做),以便我可以使用这些数据。

返回jsonObject 会更好,这样我就可以使用这样的东西:

SomeType response = Net.createNetworkThread(...);

或者,在NetworkManager 中拥有一个由方法设置的类变量,以便像这样调用和引用它:

Net.createNetworkThread(...);
SomeType response = Net.someVariable;

或者有什么更合理的方式来接收这些数据?

我还调用了两次new OkHttpClient() - 一次在活动中,所以我可以构建requestBody 后变量,以及NetworkManager 类本身。我的直觉告诉我这是多余的……如果是这样,有没有办法让它更有效率?

提前致谢!

【问题讨论】:

  • @TimCastelijns OkHttp 是一个 Http 客户端。喜欢 HttpUrlConnection
  • @TimCastelijns 有人告诉我的朋友要确保始终将网络请求保留在单独的线程中。如果它已经完成了,我会想象从代码中删除 Runnable 对象,但我最初关于如何强制转换方法的问题仍然存在。
  • 您可以使用委托对象来获取结果。一个例子here
  • 啊哈,我读错了文档

标签: java android casting okhttp


【解决方案1】:

您可以像这样将 OkHttp 与 AysncTask 一起使用:

public class Webservice extends AsyncTask<String, String, UserResponse> {

private String TAG = Webservice.class.getSimpleName();
private static final String ENDPOINT = "YOUR_URL";
private static final Moshi MOSHI = new Moshi.Builder().build();
private static final JsonAdapter<UserResponse> CONTRIBUTORS_JSON_ADAPTER_RESPONSE = MOSHI.adapter(Types.newParameterizedType(UserResponse.class, UserResponse.class));

UserResponse webResponse;
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
String postBody = "postBody\n";

@Override
protected UserResponse doInBackground(String... parmas) {
    OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
    Call call = okHttpClient.build().newCall(new Request.Builder()
            .url(ENDPOINT)
            .post(RequestBody.create(JSON, postBody))
            .addHeader("Content-Type", "application/json")
            .build());

    try {
        Response response = call.execute();
        adModelResponse = CONTRIBUTORS_JSON_ADAPTER_RESPONSE.fromJson(response.body().source());

    } catch (IOException e) {
        e.printStackTrace();
    }
    return webResponse;
}

@Override
protected void onPostExecute(UserResponse adModelResponse) {


}
}

然后像这样在 Activity 调用中:

Webservice webservice = new Webservice();
webservice.execute("YOUR_PARAMETER");

使用的库:

okhttp-3.2.0、moshi-1.1.0、okio-1.8.0

【讨论】:

    【解决方案2】:

    使 NetworkManager 抽象并添加一个抽象方法,例如 public abstract void onResult(JSONObject response); 并覆盖此方法,如

    final NetworkManager Net = new NetworkManager(this){
    @Override
    public void onResult(JSONObject response){
    //do whatever you want here
    }
    };
    

    并从createNetworkThread 完成后调用此方法

    .....
    response = client.newCall(request).execute();
                    String stringResponse = response.body().string();
                    JSONObject jsonResponse = new JSONObject(stringResponse);
    onResult(jsonResponse);
    ......
    

    【讨论】:

      【解决方案3】:

      您可以使用回调接口将数据返回到您的活动中。考虑下面的例子:

      public interface JsonResponse {
         onResponseReceived(JSONObject response);
      }
      

      那么您的createNetworkThread 将如下所示:

      public void createNetworkThread(Context context, final String requestURI, final RequestBody formParameters, JsonResponse responseCallback) {
          if (!this.isConnected(context)) return;
      
          Runnable runnable = new Runnable() {
              @Override
              public void run() {
                  OkHttpClient client = new OkHttpClient();
                  Request request = new Request.Builder().url(requestURI).post(formParameters).build();
      
                  Response response = null;
      
                  // Send login request, get response //
      
                  try {
                      response = client.newCall(request).execute();
                      String stringResponse = response.body().string();
                      JSONObject jsonResponse = new JSONObject(stringResponse);
                      responseCallback.onResponseReceived(jsonResponse); // This line will return to your caller
      
                      Log.d("Net", "Request send and received!");
      
                  } catch (IOException e) {
                      Log.d("Net", "Failed");
                      e.printStackTrace();
                  } catch (JSONException e) {
                      e.printStackTrace();
                  }
              }
          };
      
          Thread thread = new Thread(runnable);
          thread.start();
      }
      

      最后是调用者:

      Net.createNetworkThread(SignupActivity.this, requestURI, formVars, new JsonResponse() {
                  @Override
                  public void onResponseReceived(JSONObject response) {
                      // Do stuff in your activity
                      // eventually use runOnUiThread for your UI operations 
                  }
              });
      

      【讨论】:

        猜你喜欢
        • 2013-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 2011-04-30
        • 2017-05-27
        • 2020-04-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多