Android 从 Okhttp onResponse 函数中提取字符串

Android Extract String from Okhttp onResponse Function

我想使用 Android Studio 从 OkHttp3 中的 onResponse 函数获取字符串值,即

final String title_name = jsonarray_news_extract_Data(jsonStr, index)

在下面的代码中。 我试过在参数中插入字符串变量 "a",但它说

Variable is accessed within inner class. Needs to be declared final

所以我声明为 final 然后它说

Cannot Assign a Value to Final Variable

我试着把

a = title_name;

删除 Handler 方法后仍然无效。

如果你有任何想法,请帮助我。 谢谢

public void news_From_API_Title(String url_news, final int index, final TextView textView, String a){

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            .url(url_news)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {}

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
            final String jsonStr = Objects.requireNonNull(response.body()).string();
            final String title_name = jsonarray_news_extract_Data(jsonStr, index);

            Handler mainHandler = new Handler(Looper.getMainLooper());
            mainHandler.post(new Runnable() {
                @Override
                public void run() {

                    a = title_name;
                }
            });
        }
    });

}

private String jsonarray_news_extract_Data(String jsonString_News, int index){
    try {
        JSONObject jsonObject = new JSONObject(jsonString_News);
        JSONArray jsonArray = jsonObject.getJSONArray("Data");
        return jsonArray.getJSONObject(index).getString("title");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return null;
}

您可以像这样使用自定义 interface

interface ApiCallback{
    void onOkHttpResponse(String data);
    void onOkHttpFailure(Exception exception);
}

然后你传递的不是 String 而是 ApiCallback 的实例到实际执行调用的方法中:

public void news_From_API_Title(String url_news, final int index, final TextView textView, ApiCallback callback){

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            .url(url_news)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
            callback.onOkHttpFailure(e);
        }

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
            final String jsonStr = Objects.requireNonNull(response.body()).string();
            final String title_name = jsonarray_news_extract_Data(jsonStr, index);

            Handler mainHandler = new Handler(Looper.getMainLooper());
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    callback.onOkHttpResponse(title_name);
                }
            });
        }
    });

}

现在您可以使用 ApiCallback 的实现如下:

String url_news = "https://some.web.address/news";
int index = 7;
TextView textView;
news_From_API_Title(url_news, index, textView, new apiCallback(){
    @Override
    public void onOkHttpResponse(String data){
        // do something with data here
        Log.d("TEST", "data = " + data);
    }

    @Override
    onOkHttpFailure(Exception exception){
        // exception handling
    }
});

请注意,从体系结构的角度来看,如果您不将 TextView 作为参数传递到方法中,而是将文本设置为 onOkHttpResponse():[=20,可能会更好=]

// TextView will be initialized before calling news_From_API_Title()
// either make TextView a field (then use "private") 
// or declare it locally (then use "final")
private TextView textView;

// ... other code ...

String url_news = "https://some.web.address/news";
int index = 7;

// method will only take parameters which are not related to the UI 
// since it's desirable to avoid tight coupling of networking and UI components 
news_From_API_Title(url_news, index, new apiCallback(){
    @Override
    public void onOkHttpResponse(String data){
        // do something with data here
        // e.g. show data in TextView
        textView.setText(data);
    }

    @Override
    onOkHttpFailure(Exception exception){
        // exception handling
    }
});