我得到了这个例外,"无法调用Looper.prepare()"的线程内部创建处理程序,当我调用get或getFriends时抛出。这是我用于getFriends的代码。它是从主线程中调用的。
public void returnFriendIDs(final int pointer){
Properties properties = new Properties.Builder()
.add(Profile.Properties.ID)
.add(Profile.Properties.FIRST_NAME)
.add(Profile.Properties.LAST_NAME)
.add(Profile.Properties.INSTALLED)
.build();
try{
mSimpleFacebook.getFriends(properties, new OnFriendsListener() {
@Override
public void onComplete(List<Profile> friends) {
String resultStr = "";
Log.d(LOGPREFIX, "Number of friends = " + friends.size());
for(Profile p : friends){
resultStr += p.getId()+',';
}
if(friends.size() > 0) returnFriends(pointer, resultStr.substring(0,resultStr.length()-1));
else returnFriends(pointer, "");
}
@Override
public void onFail(String reason){
returnFriends(pointer, "");
}
@Override
public void onException(Throwable throwable){
Log.w(LOGPREFIX, throwable.getMessage());
returnFriends(pointer, "");
}
});
}
catch(Throwable throwable){
Log.w(LOGPREFIX, "In getFriends"+throwable.getMessage());
}
}
我在调用getFriends之前尝试调用Looper.prepare(),但这只会导致没有调用任何回调。
我的onActivityResult功能是
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//Log.w(LOGPREFIX, "onActivityResult() called.");
mSimpleFacebook.onActivityResult(this, requestCode, resultCode, data);
// Handle InApp Purchase call results
if(REQUEST_INAPP_PURCHASE == requestCode)
{
if (!mBillingHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
堆栈跟踪是:
Pending exception java.lang.RuntimeException thrown by 'unknown throw location'
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at void android.os.Handler.<init>(android.os.Handler$Callback, boolean) (Handler.java:200)
at void android.os.Handler.<init>() (Handler.java:114)
at void com.facebook.RequestAsyncTask.onPreExecute() (RequestAsyncTask.java:146)
at android.os.AsyncTask android.os.AsyncTask.executeOnExecutor(java.util.concurrent.Executor, java.lang.Object[]) (AsyncTask.java:587)
at android.os.AsyncTask android.os.AsyncTask.execute(java.lang.Object[]) (AsyncTask.java:535)
at void com.sromku.simple.fb.actions.GetAction.runRequest(com.facebook.Request) (GetAction.java:143)
at void com.sromku.simple.fb.actions.GetAction.executeImpl() (GetAction.java:81)
at void com.sromku.simple.fb.actions.AbstractAction.execute() (AbstractAction.java:17)
at void com.sromku.simple.fb.SimpleFacebook.getFriends(com.sromku.simple.fb.entities.Profile$Properties, com.sromku.simple.fb.listeners.OnFriendsListener) (SimpleFacebook.java:594)
at void com.fillmyblank.app.FillMyBlank.returnFriendIDs(int) (FillMyBlank.java:325)
at void org.libsdl.app.SDLActivity.nativeInit() (SDLActivity.java:-2)
at void org.libsdl.app.SDLMain.run() (SDLActivity.java:509)
at void java.lang.Thread.run() (Thread.java:818)
使用我的main函数(我认为是UI线程)中的代码调用它。我使用ndk所以主函数我的意思是实际的函数main。
aEnv = (JNIEnv *)SDL_AndroidGetJNIEnv();
aActivityClass = aEnv->FindClass(mClassPath.c_str());
aStaticMid = aEnv->GetStaticMethodID(aActivityClass, "GetActivity", "()Lcom/fillmyblank/app/FillMyBlank;");
aActivity = aEnv->CallStaticObjectMethod(aActivityClass, aStaticMid);
friends* fp = new friends;
fp->waiting = SDL_CreateCond();
aJavaMethodID = aEnv->GetMethodID(aActivityClass, "returnFriendIDs", "(I)V");
aEnv->CallVoidMethod(aActivity, aJavaMethodID, fp);
编辑:添加了堆栈跟踪
编辑:添加了调用函数。
答案 0 :(得分:2)
异常出现在onPreExecute
的 AsyncTask
部分,该部分属于Facebook库(com.facebook.RequestAsyncTask
)。
onPreExecute
在与AsyncTask的调用者相同的线程中执行。如果调用者是ui线程,没问题,它将起作用。调用者不是ui线程,它可能会失败(很有可能)。如果使用ui的任何组件或与ui相关的组件,它将失败。
在你的情况下,它不是在ui线程中执行,而是在没有消息循环的常规线程中执行,因此引发了这个着名的异常:Can't create handler inside thread that has not called Looper.prepare()
您必须使用runOnUiThread方法来确保您的代码在ui线程中执行。 runOnUiThread
将Runnable
作为参数。
public void returnFriendIDs(final int pointer)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
Properties properties = new Properties.Builder()
.add(Profile.Properties.ID)
.add(Profile.Properties.FIRST_NAME)
.add(Profile.Properties.LAST_NAME)
.add(Profile.Properties.INSTALLED)
.build();
try{
mSimpleFacebook.getFriends(properties, new OnFriendsListener() {
@Override
public void onComplete(List<Profile> friends) {
String resultStr = "";
Log.d(LOGPREFIX, "Number of friends = " + friends.size());
for(Profile p : friends){
resultStr += p.getId()+',';
}
if(friends.size() > 0) returnFriends(pointer, resultStr.substring(0,resultStr.length()-1));
else returnFriends(pointer, "");
}
@Override
public void onFail(String reason){
returnFriends(pointer, "");
}
@Override
public void onException(Throwable throwable){
Log.w(LOGPREFIX, throwable.getMessage());
returnFriends(pointer, "");
}
});
}
catch(Throwable throwable){
Log.w(LOGPREFIX, "In getFriends"+throwable.getMessage());
}
}
});
}