调用 getFriends 时引发异常



我得到这个异常,"无法在未调用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(),但这只会导致没有调用任何回调。

我的活动结果函数是

@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)

它是用我的主函数(我相信是 UI 线程)的这段代码调用的。我使用 ndk,所以主函数是指实际的函数主函数。

    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);

编辑:添加了堆栈跟踪

编辑:添加了调用函数。

解释

异常被抛出在AsyncTaskonPreExecute部分,该部分是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 线程中执行。 runOnUiThreadRunnable作为参数。

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());
            }
        }
    });
}

相关内容

  • 没有找到相关文章