Android Извлечение строки из функции Okhttp onResponse - PullRequest
1 голос
/ 07 марта 2020

Я хотел бы получить строковое значение из функции onResponse в OkHttp3, используя Android Studio, что означает

final String title_name = jsonarray_news_extract_Data (jsonStr, index)

в кодах ниже. Я попытался вставить строковую переменную "a" в аргументе, но он сказал

Переменная доступна во внутреннем классе. Должен быть объявлен final

, поэтому я объявил final, тогда он сказал:

Невозможно присвоить значение для конечной переменной

Я пытался поставить

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

1 Ответ

0 голосов
/ 08 марта 2020

Вы можете использовать пользовательский 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():

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