2014-02-21 61 views
1

我需要使用我的Android應用程序中的FACEBOOK GRAPH API。我爲Android下載了Facebook SDK,並研究了使用SDK給出的示例。我還研究了一個標題爲GraphApiSample的樣本。在此示例中,一批請求的使用執行下面的方法:android.os.NetworkOnMainThreadException當執行Facebook的請求圖形API

Request.executeBatchAndWait(Collection<Request> requests) 

好了,現在我想執行一個請求,但我得到android.os.NetworkOnMainThreadException在執行請求。到目前爲止,我知道這個異常發生在我們想要在不使用AsyncTask/Thread的情況下嘗試執行HTTP請求。但在FB樣本「GraphApiSample」中,它們執行的請求沒有任何線程,並且工作良好。那麼我的請求有什麼問題?

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.firstfbandroidapp" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="11" 
     android:targetSdkVersion="16" /> 

    <uses-permission android:name="android.permission.INTERNET" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.example.firstfbandroidapp.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity 
      android:name="com.facebook.LoginActivity" 
      android:label="@string/app_name" 
      android:theme="@android:style/Theme.Translucent.NoTitleBar" /> 

     <meta-data 
      android:name="com.facebook.sdk.ApplicationId" 
      android:value="@string/app_id" /> 

     <activity 
      android:name="com.example.firstfbandroidapp.AnotherActivity" 
      android:label="@string/title_activity_another" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".MainActivity" > 

    <TextView 
     android:id="@+id/welcome" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_centerVertical="true" 
     android:text="TextView" /> 

    <Button 
     android:id="@+id/login_with_fb" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/welcome" 
     android:layout_centerHorizontal="true" 
     android:text="Login with Facebook" /> 

    <com.facebook.widget.LoginButton 
     android:id="@+id/authButton" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignLeft="@+id/login_with_fb" 
     android:layout_alignParentTop="true" 
     android:layout_marginTop="47dp" /> 

    <Button 
     android:id="@+id/execute_request" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/login_with_fb" 
     android:layout_centerHorizontal="true" 
     android:text="Execute Request" /> 

</RelativeLayout> 

MainActivity.java

package com.example.firstfbandroidapp; 

import java.util.ArrayList; 
import java.util.List; 

import org.json.JSONObject; 

import com.facebook.*; 
import com.facebook.model.*; 

import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.util.Log; 
import android.view.View.OnClickListener; 

import android.os.Bundle; 
import android.app.Activity; 
import android.view.Menu; 
import android.view.View; 

public class MainActivity extends Activity { 

    Button loginWithFB; 
    Button executeRequest; 

    private Session session; 
    private Session.StatusCallback statusCallback = new SessionStatusCallback(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     loginWithFB = (Button) findViewById(R.id.login_with_fb); 
     executeRequest = (Button) findViewById(R.id.execute_request); 
     executeRequest.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       session = Session.getActiveSession(); 
       if (session.isOpened()) { 
        sendRequest(); 
       } else { 
        Toast.makeText(getApplicationContext(), "No Active Session", Toast.LENGTH_LONG).show(); 
       } 
      } 
     }); 

     session = Session.getActiveSession(); 
     if(session == null) { 
      if(savedInstanceState != null) { 
       session = Session.restoreSession(this, null, statusCallback, savedInstanceState); 
      } 
      if(session == null) { 
       session = new Session(this); 
      } 
      Session.setActiveSession(session); 
      Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS); 
      if(session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) { 
       session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback)); 
      } 
     } 
     updateView(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     Session.getActiveSession().addCallback(statusCallback); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     Session.getActiveSession().removeCallback(statusCallback); 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); 
    } 

    private void sendRequest() 
    { 
     Session session = Session.getActiveSession(); 
     Request request = new Request(session, "me", null, HttpMethod.GET, new Request.Callback() { 
      @Override 
      public void onCompleted(Response response) { 
       GraphObject graphObject = response.getGraphObject(); 
       FacebookRequestError error = response.getError(); 
       if (graphObject != null) { 
        JSONObject jsonObject = graphObject.getInnerJSONObject(); 
        Log.d("MY_TAG", jsonObject.toString()); 
        if (graphObject.getProperty("id") != null) { 
         Toast.makeText(getApplicationContext(), (String)graphObject.getProperty("id"), Toast.LENGTH_LONG).show(); 
        } 
        //System.out.println(jsonObject.toString()); 
       } 
      } 
     }); 
     Request.executeAndWait(request); 
    } 

    private void updateView() { 
     Session session = Session.getActiveSession(); 
     if (session.isOpened()) { 
      loginWithFB.setText("Logout"); 
      loginWithFB.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        onClickLogout(); 
        loginWithFB.setText("Login with Facebook"); 
       } 
      }); 
     } else { 
      loginWithFB.setText("Login with Facebook"); 
      loginWithFB.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        onClickLogin(); 
       } 
      }); 
     } 
    } 

    private void onClickLogin() { 
     Session session = Session.getActiveSession(); 
     if (!session.isOpened() && !session.isClosed()) { 
      session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback)); 
     } else { 
      Session.openActiveSession(this, true, statusCallback); 
     } 
    } 

    private void onClickLogout() { 
     Session session = Session.getActiveSession(); 
     if (!session.isClosed()) { 
      session.closeAndClearTokenInformation(); 
     } 
    } 

    private class SessionStatusCallback implements Session.StatusCallback { 
     @Override 
     public void call(Session session, SessionState state, Exception exception) { 
      updateView(); 
     } 
    } 
} 
+0

您是否試圖在asynctask上執行請求? – Giacomoni

+0

你的問題很長。幾乎所有你發佈的內容都是不必要的 - 佈局如何影響這一點?你沒有發佈的是你的LogCat,如果你有人可以提供更具體的幫助 - 看看它也可以讓你找出什麼是相關的後 –

+0

沒有。我沒有嘗試使用AsyncTask,但是我使用AsyncTask來執行各種HTTP請求。現在我將嘗試使用AsyncTask。 @giacomoni –

回答

1

這僅適用於定位到Honeycomb SDK(v11)或更高版本的應用程序。針對早期SDK版本的應用程序允許在其主要事件循環線程上進行聯網,但非常不鼓勵。由於您使用android:targetSdkVersion="16"(果凍豆),您必須在另一個線程上運行網絡操作。

+0

嗨尼基斯。你是對的。我只注意到FB樣本定義了minSdkVersion = 8,並沒有設置任何targetSdkVersion。我使用minSdkVersion = 9測試了我的代碼,它可以工作。我對AsyncTask很滿意,並讓我嘗試使用AsyncTask。這就是我的愚蠢。 :( –

相關問題