调用getFriends时抛出异常

时间:2014-12-25 03:26:44

标签: java android android-simple-facebook

我得到了这个例外,"无法调用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);

编辑:添加了堆栈跟踪

编辑:添加了调用函数。

1 个答案:

答案 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线程中执行。 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());
            }
        }
    });
}