HandlerThread handleMessage() не вызывается

Я только что столкнулся со странной проблемой при использовании HandlerThread и Handlers (под Handlers я имею в виду android.os.handler). Я пытаюсь передать сообщение из своего фрагмента в отдельный поток обработчика. Я просто настроил handleMessage для обработки сообщения. Но не называется. У меня есть петлитель для потока обработчика после запуска потока с помощью start() (после того, как петлитель подготовлен). Я также проверил, что обработчик получил сообщение, используя hasMessage(). все хорошо. Я запутался. пожалуйста, помогите мне. Мои коды ниже.

Код фрагмента:

   package com.example.raaja.handlerone;

import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;





/**
 * Created by Raaja on 08-12-2015.
 */
public class LoaderFragment extends Fragment {
    Button loaderButton;
    LoaderThread loadThread;
    Handler loaderThreadHandler;
    Handler loaderHandler;
    String[] queArray;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        loaderHandler = new Handler();
        loadThread = new LoaderThread("LoaderThread",loaderHandler);
         queArray = new String[]{"http://www.paynekillers.com/downloads/screens/17_screen05.jpg",
                "http://www.hdwallpapers.in/walls/jacob_frye_assassins_creed_syndicate-wide.jpg",
        "http://www.percivalconstantine.com/wp-content/uploads/2015/03/Tomb-Raider-Lara-Croft-Summit-2013.jpg",
        "http://orig00.deviantart.net/f904/f/2014/155/e/a/batman_arkham_knight_hd_wallpaper_1_by_rajivcr7-d7l19pt.jpg",
        "http://static5.gamespot.com/uploads/original/536/5360430/2753139-15774024117_9026e0a43c_o.jpg"};
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View loaderView = inflater.inflate(R.layout.loader_layout, container, false);
        this.loaderButton = (Button) loaderView.findViewById(R.id.proc_button);
        return loaderView;
    }

    @Override
    public void onResume() {
        super.onResume();



        loaderButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loadThread.start();
                Looper loop = loadThread.requestLooper();
                loaderThreadHandler = new Handler(loop);
                Message msg = Message.obtain(loaderThreadHandler, 1, queArray);
                msg.sendToTarget();


            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        loadThread.quit();
    }
}

Поток обработчика

 package com.example.raaja.handlerone;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * Created by Raaja on 08-12-2015.
 */
public class LoaderThread extends HandlerThread implements Handler.Callback{
    Handler imageHandler;
    Map<Integer,String> queMap;
    HandlerActivity activity;

    public LoaderThread(String name, Handler handler) {
        super(name);
        imageHandler= handler;
        Log.d("inside : ", name);
    }

    Looper requestLooper(){

        Looper loop = this.getLooper();
        Log.d("In Thread : ", String.valueOf(loop.getThread().getName()));
        return loop.myLooper();
    }


    @Override
    public boolean handleMessage(Message msg) {
        String[] que = (String[]) msg.obj;
        queMap = new HashMap<Integer,String>();
        if(que != null){Log.d("",que[3]);}
        for (int i=0;i<=4; i++){
            String url = que[i];

            queMap.put(i,url);
            Log.d("1",url);
        }
        Random rand = new Random();
       String link = queMap.get(rand.nextInt(5));

        loadImages(link);
        return true;
    }

    void loadImages(final String url){
        Log.d("inside Load :","Inside Load");
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            final Bitmap image = BitmapFactory.decodeStream(connection.getInputStream());
            imageHandler.post(new Runnable() {
                @Override
                public void run() {
                    activity.loadImage(image, url);
                }
            });

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

person Raaja SN    schedule 10.12.2015    source источник
comment
нет, нет, нет, вам нужно: ht = new HandlerThread("..."); ht.start(); h = new Handler(ht.getLooper()) {...   -  person pskink    schedule 10.12.2015
comment
@pskink вот что я сделал. LoaderThread выше я расширил класс HandlerThread. Как вы сказали, я сделал то же самое. Вызывается loadThread = new LoaderThread(..); при создании(). Я вызвал loadThread.start(); и loaderThreadHandler = новый обработчик (цикл);. Я попытался вызвать новый Handler(loadThread.getLooper()); Это моя первая версия, и я получаю тот же результат.   -  person Raaja SN    schedule 11.12.2015
comment
нет, вы продлили HandlerThread, это не обязательно, просто следуйте моим 3 шагам   -  person pskink    schedule 11.12.2015
comment
@pskink Я просто хочу расширить новый HandlerThread. Надеюсь, вы предлагаете мне создать поток внутри Фрагмента (innerThread). Это так? Если да, то какая разница при его расширении?   -  person Raaja SN    schedule 11.12.2015
comment
запустите его сразу после создания (в Fragment#onCreate)   -  person pskink    schedule 11.12.2015
comment
@pskink Почему так? Пожалуйста, скажите мне разницу. Я просто хотел запустить поток только при нажатии кнопки. Я думал, что таким образом я буду запускать тему только тогда, когда мне нужно, и не трачу ресурсы впустую? я прав?   -  person Raaja SN    schedule 11.12.2015
comment
хорошо, так что запускайте его при нажатии кнопки, без разницы   -  person pskink    schedule 11.12.2015
comment
@pskink хорошо, но моя проблема не решена? у вас есть предположения, почему не вызывается handleMessage?   -  person Raaja SN    schedule 11.12.2015
comment
Вы пытались выполнить мои 3 шага?   -  person pskink    schedule 11.12.2015
comment
да . Я попробовал, и, как я уже сказал, ваши шаги — это то, что я использовал при первом кодировании этого приложения. Тогда я решил начать тему только тогда, когда мне нужно. Но проблема сохраняется. я даже пытался вызвать handleMessage явно с помощью loadThread.handleMessage(). Сообщение вызывается, но когда оно попадает в сетевую операцию, я получаю исключение NetworkOnMainThread.   -  person Raaja SN    schedule 11.12.2015
comment
поэтому опубликуйте свой код, как вы отправляете сообщения/отправляете runnables   -  person pskink    schedule 11.12.2015
comment
Давайте продолжим это обсуждение в чате.   -  person Raaja SN    schedule 11.12.2015


Ответы (1)


ОТВЕТ НА МОЙ ВОПРОС:

Я могу отправлять сообщения и получать сообщения на свой handleMessage() из другого потока. Я уже расширил класс HandlerThread и реализовал Handler.Callback для своего класса Thread. Поэтому я просто использовал приведенную ниже версию для создания экземпляра Handler, передающего поток как обратный вызов (поскольку он реализует Handler.Callback, он был принят как обратный вызов). Я надеюсь, что это помогает. Если вы запутались, внимательно прочитайте код. Спасибо.

Handler myHandler = new Handler(myThread.getLooper(),myThread);
person Raaja SN    schedule 11.12.2015