Проблема с потоком android

215
10 января 2018, 18:31

Есть следующий код:

package tanat.androidtesttask;
import android.app.DialogFragment;
import android.app.ListFragment;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainList extends ListFragment implements SwipeRefreshLayout.OnRefreshListener{
    SwipeRefreshLayout mSwipeRefreshLayout;
    ArrayList data;
    DialogFragment dialogFragment;
    //подключаем мой фрагмент
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item, null);
        dialogFragment = new MyDialog();
        mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh);
        mSwipeRefreshLayout.setOnRefreshListener(this);
        return view;
    }
    @Override
    public void onActivityCreated(Bundle savedInstanceState){
        dialogFragment.show(getFragmentManager(), "");
        final Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                data = new MainActivity().demo();
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        dialogFragment.dismiss();

        //      dialogFragment.show(getFragmentManager(), "");
 //       data = new MainActivity().demo();
        //создаем лист фрагментов
        super.onActivityCreated(savedInstanceState);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1, data);
        setListAdapter(adapter);
    }
    @Override
    public void onStart() {
        super.onStart();
    }
    //вешаем слушатель на нажатие фрагмента
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        //передаем позицию елемента в второе активити
        //создаем интент
        Intent intent = new Intent(MainList.this.getContext(), InfoRoutActivity.class);
        //записываем в него ключ и позицию
        intent.putExtra("position", position);
        //передаем
        startActivity(intent);
    }
    //свайп вниз для обновления
    @Override
    public void onRefresh() {
        // говорим о том, что собираемся начать
        Toast.makeText(getActivity(), "Обновляем", Toast.LENGTH_SHORT).show();
        // начинаем показывать прогресс
        mSwipeRefreshLayout.setRefreshing(true);
        // ждем 3 секунды и прячем прогресс
        mSwipeRefreshLayout.postDelayed(new Runnable() {
            @Override
            public void run() {
                mSwipeRefreshLayout.setRefreshing(false);
                // говорим о том, что собираемся закончить
                Toast.makeText(getActivity(),"обновили", Toast.LENGTH_SHORT).show();
            }
        }, 3000);
    }
}

Это класс фрагмента. При его создании вызываться еще один фрагмент который представляет собой просто костомный DialogFragment вроде диалога прогреса. а командой

data = new MainActivity().demo();

переходит в активити, из него в service и загружает json затем ждем пока этот поток выполниться и закрываем диалог прогреса, а дальше создаем ListFragment из данных что скачали, так по крайней мере задумано, НО на этой самой команде выбивает следующую ошибку

E/AndroidRuntime: FATAL EXCEPTION: Thread-130
                  Process: tanat.androidtesttask, PID: 1700
                  java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
                      at android.os.Handler.<init>(Handler.java:200)
                      at android.os.Handler.<init>(Handler.java:114)
                      at android.app.Activity.<init>(Activity.java:754)
                      at tanat.androidtesttask.MainActivity.<init>(MainActivity.java:0)
                      at tanat.androidtesttask.MainList$1.run(MainList.java:50)
                      at java.lang.Thread.run(Thread.java:818)

я уже пытался использывать Handler но не могу понять как правильно его использовать в данном случае, шарюсь в интернете уже 2 дня и безрезультатно. Помогите пожалуйста Зарание спасибо.

Answer 1

Итак, Handler - это интерфейс для общения с потоком, к которому он приклеплен. В качестве параметра он принимает поток, в котором будет работать (На самом деле специальный объект класса Looper, документация по Handler). Вызов Handle handler = new Handler() {...} привязывает Handler к текущему потоку. Т.е. функции объекта будут выполнятся в его контексте создания. Это означает, что мы можем общаться с потоком посредством Handler.

Например:

HandlerThread getThread = new HandlerThread("getThread"); // Создали поток 
getThread.start(); // Запустили
getHandler = new Handler(getThread.getLooper()); // Получили объект Looper потока
getHandler.post(new Runnable() {...}); // Выдали код на исполнение потоку getThread
getHandler.obtainMessage(1, new SomeObject()); // Отослали сообщение с пользовательским типом и объект для обработки в параметре arg1.

Как видно из примера, мы создали новый поток (Заметьте, класс HandlerThread уже имеет Looper. Обычный Thread его иметь не будет и вам в ручную придется контролировать его время жизни), получили объект Looper и объявили Handler. Теперь мы можешь отправлять разные сообщение или отдать код для его исполнения в поток посредством вызова методов getHandler.

Ссылка на хороший туториал по Android для начинающих, официальный гайд и настоятельно рекомендую прочитать мой комментарии выше и прочесть статьи по ссылкам.

READ ALSO
Простой пример Сокета. Андроид

Простой пример Сокета. Андроид

Недавно узнал что такое сокет но не могу о них понять некоторы моментыГуглил но все что нашел не расчитано для новичков

209
java.lang.SecurityException

java.lang.SecurityException

при вызове

237
websocket vs socket

websocket vs socket

Доброго времени сутокВопрос такой: В чём разница между websocket'ом и socket'ом?

167
Optional&lt;Integer&gt; и OptionalInt

Optional<Integer> и OptionalInt

В чём отличие Optional<Integer> и OptionalInt, и в каких случаях какой из этих типов лучше применять?

177