-1

これは、上に投稿された質問の複製ではありません。HAndlerThread が newThread を開始し、NetworkOnMainThread 例外が発生するため、奇妙なエラーだと思います。通常の NetworkOnMainThread 例外を解決するのは、まったく新しい問題です。これをマーク解除してください。

こんにちは、まず私は HandlerThread を練習しています。Fragment を使用してハンドラ スレッドを開始し、スレッドにメッセージを送信しました。HandlerThread のハンドル メッセージ内で、ネットワーク呼び出しを使用して画像をダウンロードします。次に、MainThread のハンドラーを使用して、ダウンロードした画像を UI スレッドに投稿します。しかし、このアプリケーションを実行すると NetworkOnMainThread Exception が発生します。以下は Fragment と Handler Thread のコードです。

断片:

public class LoaderFragment extends Fragment {
Button loaderButton;
LoaderThread loadThread;
Handler loaderThreadHandler;
Handler mainHandler;
String[] queArray;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mainHandler = new Handler(Looper.getMainLooper());
    loadThread = new LoaderThread("LoaderThread",mainHandler);
     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();
            loaderThreadHandler = loadThread.requestHandler();
            Message msg = Message.obtain(loaderThreadHandler, 1, queArray);
            msg.sendToTarget();
        }
    });
}

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

ハンドラー スレッド:

public class LoaderThread extends HandlerThread implements Handler.Callback{
Handler imageHandler;
Handler loaderHandler;
Map<Integer,String> queMap;
HandlerActivity activity;


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

Handler requestHandler(){
    loaderHandler = new Handler(this.getLooper(),this);
    return loaderHandler;
}


@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);
    }
    Log.d("THR : ", String.valueOf(Thread.currentThread()));
    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();
    }
} }

アクティビティの loadImage メソッド:

public void loadImage(Bitmap image, String url) {
    Bitmap img = image;
    String link = url;
    ft = fmg.beginTransaction();
    ft.add(R.id.frag_container,imgFrag,"ImageFragment");
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.show(imgFrag);
    ft.commit();
    imgFrag.loadImg(img,link);

}

また、ログを使用して現在のスレッド (HandlerThread の handleMessage 内) を確認すると、メインにいるときにログ メッセージが表示されます。それはどのように可能ですか?私は何か間違ったことをしていますか?

4

3 に答える 3

0

私も同じ問題を抱えていました。そして、 というHandlerThread'sオーバーライドされたメソッドにハンドラーを設定し、onLooperPrepared()その例外をもう受け取らなかったので、LoaderThreadクラスで次のようなことを試みるべきです:

@Override
protected void onLooperPrepared() {
    super.onLooperPrepared();
    loaderHandler = new Handler(this.getLooper(),this);
}

onLooperPreparedドキュメンテーションによると、次のように引用します。ルーパーループの前にセットアップを実行する必要がある場合は、明示的にオーバーライドできるコールバックメソッド。これがうまくいったかどうかをここで教えてください。

于 2016-01-24T16:39:15.750 に答える
0

LoaderFragmentから乗り換え

mainHandler = new Handler(Looper.getMainLooper());
loadThread = new LoaderThread("LoaderThread",mainHandler);

loadThread = new LoaderThread("LoaderThread");

そして、LoaderThread

public LoaderThread(String name, Handler handler) {
     super(name);         
     Log.d("inside : ", name);
}
 @Override
 protected void onLooperPrepared() {
     imageHandler = new Handler(getLooper(), this);
  }

UI Thread Looper を LoaderThread に渡しているため、エラーが発生しています。LoaderThread はrequestHandler()、ネットワーク アクセスのために再度渡します。したがって、ネットワーク操作は UI スレッド ルーパーによってキューから取り出されます。

于 2016-01-19T14:18:00.463 に答える
-3

Android でのネットワーク操作では、そのコードを AsyncTask 内に記述することをお勧めします。

于 2016-01-19T12:39:07.530 に答える