【发布时间】:2016-03-16 10:34:54
【问题描述】:
我在使用 HandlerThread 和 Handlers(我指的是 android.os.handler)时遇到了一个奇怪的问题。我正在尝试将消息从我的片段传递到单独的处理程序线程。我只是设置了一个handleMessage 来处理消息。但它没有被调用。在使用 start() 启动线程后,我得到了处理程序线程的 looper(在准备好 looper 之后)。我还检查了处理程序是否使用 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();
}
}
}
【问题讨论】:
-
不,不,不,你需要的是:
ht = new HandlerThread("..."); ht.start(); h = new Handler(ht.getLooper()) {... -
@pskink 这就是我所做的。上面的 LoaderThread 我扩展了类 HandlerThread。正如你所说,我也做了同样的事情。调用 loadThread = new LoaderThread("..");在 onCreate() 上。我已经调用了 loadThread.start();和 loaderThreadHandler = new Handler(looper);。我试过调用 new Handler(loadThread.getLooper());那是我的第一个版本,我得到了相同的结果。
-
不,你扩展了
HandlerThread,你不必这样做,只需按照我的 3 个步骤进行即可 -
@pskink 我只想扩展一个新的 HandlerThread。我希望你建议我在 Fragment (innerThread) 中启动一个线程。是这样吗?如果是这样,它在扩展时有什么不同?
-
创建后立即启动它(
Fragment#onCreate)
标签: android multithreading android-handler android-handlerthread