Как изменить общедоступное строковое значение во фрагменте Android с помощью функции onResponse json

#java #android #android-fragments

#java #Android #android-фрагменты

Вопрос:

Я пытаюсь получить текст страницы из своей базы данных SQL и отобразить его в текстовом представлении во фрагменте Android.

Я получил данные, но когда я пытаюсь разобрать их в общедоступную строку, результат равен NULL.

я создал общедоступную строку pageText и использовал setText (pageText) и попытался проанализировать текст json в pageText, но результат пустой и не отображает текст страницы в TextView

вот мой код:

  package per.mikha.programs.medjobs.ui.home;

import android.app.VoiceInteractor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;

import java.io.IOException;
import java.lang.reflect.Method;

import per.mikha.programs.medjobs.R;

public class HomeFragment extends Fragment {

    private HomeViewModel homeViewModel;
    public String pageText;
    public final String GET_BY_ID = "https://xxxxxx.com/mekha.php?id=";


    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        homeViewModel =
                new ViewModelProvider(this).get(HomeViewModel.class);
        View root = inflater.inflate(R.layout.fragment_home, container, false);
        final TextView textView = root.findViewById(R.id.text_home);

        getData("1");
        textView.setText(pageText);
        //Toast.makeText(getContext(),pageText,Toast.LENGTH_LONG).show();

        /*homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });*/
        return root;

    }

    public void getData(String id){
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, GET_BY_ID id, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
       

     try {
                String title = response.getString("title");
                String theText = response.getString("text");
                pageText=theText;
                //Toast.makeText(getContext(),theText,Toast.LENGTH_LONG).show();
            } catch (JSONException e) {
                e.printStackTrace();
                Toast.makeText(getContext(),e.getMessage(),Toast.LENGTH_LONG).show();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(getContext(),error.getMessage(),Toast.LENGTH_LONG).show();
        }
    });

    RequestQueue requestQuere = Volley.newRequestQueue(getContext());
    requestQuere.add(request);
}
}
 

Ответ №1:

Удалите переменную pagetext и установите textview для ответа

Ответ №2:

Давайте разберем это на части:

     final TextView textView = root.findViewById(R.id.text_home);

    getData("1");
    textView.setText(pageText);
 

и вы говорите, что pageText — это null когда setText вызывается. Итак, давайте посмотрим, что getData делает:

 public void getData(String id){
    JsonObjectRequest request = 
            new JsonObjectRequest(
                Request.Method.GET, GET_BY_ID id, null, 
                new Response.Listener<JSONObject>() {
                     @Override
                     public void onResponse(JSONObject response) {
                         try {
                             String title = response.getString("title");
                             String theText = response.getString("text");
                             pageText = theText;
                         } catch (JSONException e) {
                             // ...
                         }
                    }
               }, 
               new Response.ErrorListener() {
                    // ...
               }
    );
    RequestQueue requestQueue = Volley.newRequestQueue(getContext());
    requestQueue.add(request);
}
 

Итак… getData подготавливает запрос с помощью прослушивателя ответов и обработчика ошибок, добавляет его в очередь запросов и затем немедленно возвращает.

Через некоторое время запрос отправляется, и ответ получен. Затем onResponse вызывается метод, JSON анализируется и pageText устанавливается в (предположительно) ненулевое значение.

Но вот в чем проблема. Как только getData вызов возвращается, вызывающий делает это:

     textView.setText(pageText);
 

Скорее всего, ответ на запрос еще не поступил и еще pageText не был установлен. Упс.

Но я не думаю, что вы сможете дождаться ответа, прежде чем вернуться getData . Это заблокировало бы поток пользовательского интерфейса. Итак, я думаю, вам нужно сделать, это поместить код, который вызывает textView.setText onResponse метод прослушивателя ответа.

Ответ №3:

Для вашего намерения метод ‘getData’ должен работать синхронно. Но ваш код не работает.
Чтобы убедиться, что он работает правильно, измените метод ‘getData’ для синхронизации или вызовите метод ‘setText’ после метода ‘onResponse’.