Я пытаюсь освоить многопоточность в Android. Моя цель - отправить данные из основного потока в рабочий поток.
У меня есть основное действие со следующим кодом в его onCreate-
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ThreadOne threadOne = new ThreadOne();
threadOne.start();
threadOneLooper = threadOne.getLooper();
Message msg = new Message();
msg.obj = "message.";
Log.i("id--(threadOneLooper)", String.valueOf(threadOneLooper.getThread().getId()));
Log.i("id--(Main)", String.valueOf(getMainLooper().getThread().getId()));
TestHandler mHandler = new TestHandler(threadOneLooper);
mHandler.handleMessage(msg);
}
Как вы можете заметить, я сохраняю ссылку на петлитель рабочего потока в threadOneLooper, а затем регистрирую идентификатор связанного с ним потока.
В то же время я также печатаю идентификатор основного потока.
Ниже приведен код для моего потока -
public class ThreadOne extends Thread{
@Override
public void run() {
if (Looper.myLooper() == null)
Looper.prepare();
Log.i("ThreadOne", "run()");
// Just making sure all approaches give the same result
Log.i("Id--Thread id 1", String.valueOf(getLooper().getThread().getId()));
Log.i("Id--Thread id 2", String.valueOf(getId()));
Looper.loop();
}
Looper getLooper() {
if (Looper.myLooper() != null)
return Looper.myLooper();
else
return null;
}
И ниже приведен код моего обработчика -
public class TestHandler extends Handler {
TestHandler(Looper myLooper) {
super(myLooper);
}
public void handleMessage(Message msg) {
String txt = (String) msg.obj;
Log.i("Handler", txt);
Log.i("Id--(Handler)", String.valueOf(getLooper().getThread().getId()));
}
}
Теперь проблема в том, что я предположил, что оператор Log.i("Id--(Handler)", String.valueOf(getLooper().getThread().getId())); будет регистрировать идентификатор потока ThreadOne, поскольку мы передаем цикл обработки потока в обработчик. Однако регистрируемый идентификатор относится к основному потоку. Почему это? Правильно ли предположить, что handleMessage() выполняется в основном потоке?
Основная причина в том, что вы создали обработчик внутри основного потока, поэтому этот обработчик всегда перехватывает сообщения, поступающие в основной поток.
@Jasurbek Но я передаю петлитель рабочего потока в обработчик. Разве обработчик не должен ассоциировать себя с работником в этом случае?
У меня пока нет ответа. Но я понял, что мой подход был неправильным - stackoverflow.com/questions/37671500/… Использование вашего подхода дает мне исключение нулевого указателя.




Проблема с getLooper() методом ThreadOne. Метод возвращает мойЛупер(), связанный с потоком, вызвавшим метод.
Для возврата Лупер, связанного с ThreadOne, я бы предложил следующую реализацию класса:
public class ThreadOne extends Thread {
private Looper mLooper = null;
@Override
public void run() {
Looper.prepare();
mLooper = Looper.myLooper();
Looper.loop();
}
Looper getLooper() {
return mLooper;
}
}
Примечание!ЛуперThreadOne равен null, пока он не запущен. Вы не можете получить не-null ссылку на него ранее. Вы должны проверить, запущен ли поток перед вызовом метода getLooper().
P.S. Возможно, вы захотите пересмотреть подход к получению ЛуперThreadOne. Наличие Обработчик, связанного с ThreadOne, может быть достаточным (посмотреть пример треда).
Пожалуйста, пройдите через Android Looper, Handler и MessageQueue. Это даст вам ответ blog.mindorks.com/…