0

我得到这个异常,“无法在未调用 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)

它是从我的主函数(我相信它是 UI 线程)中用这段代码调用的。我使用 ndk,所以 main 函数是指实际的 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);

编辑:添加堆栈跟踪

编辑:添加了调用功能。

4

1 回答 1

2

说明

在 Facebook 库 ( )的onPreExecute一部分中抛出异常。AsyncTaskcom.facebook.RequestAsyncTask

onPreExecute在与 AsyncTask 的调用者相同的线程中执行。如果调用者是 ui 线程,没问题,它会工作。如果调用者不是 ui 线程,它可能会失败(很有可能)。如果使用了 ui 的任何组件或与 ui 相关的任何组件,都会失败。

在您的情况下,它不是在 ui 线程中执行,而是在没有消息循环的常规线程中执行,因此抛出了这个著名的异常:Can't create handler inside thread that has not called Looper.prepare()

解决方案

您必须使用runOnUiThread方法来确保您的代码在 ui 线程中执行。runOnUiThread将 aRunnable作为参数。

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());
            }
        }
    });
}
于 2014-12-29T13:32:03.100 回答