Как Fragment может получить данные из класса MainActivity, которые получают данные с помощью задачи http и asycn? - PullRequest
0 голосов
/ 12 октября 2019

Я создаю приложение для Android с помощью Android Studio. Я пользуюсь шаблоном Navigation Drawer. Я хочу показать данные из Интернета, используя http и асинхронную задачу в домашнем фрагменте. Я копирую код вставки класса из Интернета, который извлекает данные из Интернета.

Это класс:

    class FetchThingspeakTask extends AsyncTask<Void, Void, String> {
        protected void onPreExecute() {
            Toast.makeText(getApplicationContext(), "Fetching Data from Server.Please Wait...", Toast.LENGTH_SHORT).show();
        }
        protected String doInBackground(Void... urls) {
            try {
                URL url = new URL("https://api.thingspeak.com/channels.json?api_key=I9CEDD46LZX2HZTC");
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                try {
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    StringBuilder stringBuilder = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        stringBuilder.append(line).append("\n");
                    }
                    bufferedReader.close();
                    return stringBuilder.toString();
                }
                finally{
                    urlConnection.disconnect();
                }
            }
            catch(Exception e) {
                Log.e("ERROR", e.getMessage(), e);
                return null;
            }
        }
        protected void onPostExecute(String response) {
            if(response == null) {
                Toast.makeText(MainActivity.this, "There was an error", Toast.LENGTH_SHORT).show();
                return;
            }
 // I want to get this response and use it in any fragment
            Toast.makeText(getApplicationContext(), response, Toast.LENGTH_LONG).show();
        }
    }

Я помещаю этот класс в MainActivity.java и выполняю его в основной деятельности. Я выполняю этот класс каждую минуту, используя таймер и обработчик.

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

это полный основной код активности:


public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        setRepeatingAsyncTask();

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
                R.id.nav_tools, R.id.nav_share, R.id.nav_send)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

    class FetchThingspeakTask extends AsyncTask<Void, Void, String> {
        protected void onPreExecute() {
            Toast.makeText(getApplicationContext(), "Fetching Data from Server.Please Wait...", Toast.LENGTH_SHORT).show();
        }
        protected String doInBackground(Void... urls) {
            try {
                URL url = new URL("https://api.thingspeak.com/channels.json?api_key=I9CEDD46LZX2HZTC");
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                try {
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    StringBuilder stringBuilder = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        stringBuilder.append(line).append("\n");
                    }
                    bufferedReader.close();
                    return stringBuilder.toString();
                }
                finally{
                    urlConnection.disconnect();
                }
            }
            catch(Exception e) {
                Log.e("ERROR", e.getMessage(), e);
                return null;
            }
        }
        protected void onPostExecute(String response) {
            if(response == null) {
                Toast.makeText(MainActivity.this, "There was an error", Toast.LENGTH_SHORT).show();
                return;
            }
            // I want to get this response and use it in any fragment
            Toast.makeText(getApplicationContext(), response, Toast.LENGTH_LONG).show();
        }
    }

    private void setRepeatingAsyncTask() {

        final Handler handler = new Handler();
        Timer timer = new Timer();

        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        try {
                            new FetchThingspeakTask().execute();
                        }
                        catch(Exception e){
                            Log.e("ERROR", e.getMessage(), e);
                        }
                    }
                });
            }
        };

        timer.schedule(task, 0, 60*1000);  // interval of one minute

    }
}

Есть ли какие-либо предложения, как это сделать?

Обновление:

Я хочу, чтобы этот ответ былдинамически обновлять фрагмент

1 Ответ

0 голосов
/ 13 октября 2019

Объявите глобальную переменную для фрагмента

Fragment fragmentRef = new MyFragment() // your fragment name

Теперь внутри onPostExecute ()

Для самого первого вызова API сделайте вашу транзакцию фрагмента, значит, раздувать фрагмент из действия

getFragmentManager().beginTransaction().replace(R.id.container, fragmentRef, "TAG).commit()

make setData () метод во фрагменте и вызов с использованием fragreef

fragmentRe.setData(response) //pass your data

Теперь для следующих / последующих вызовов API проверьте и получите свой фрагмент из fragManager с помощью findFragmentByTag (),как только вы получите ссылку на фрагмент, вызовите setData () Method

if( fragmentRef !=null){
    fragmentRef.setData(response)
  }
...