如果您导入facebook SDK库,代码可以正常工作(忽略现在使用的弃用方法lol),并且没有错误或警告。
然而,当我在Android 2.2或4.2模拟器上运行我的Facebook应用程序时,应用程序在打开时或登录屏幕后崩溃。为什么呢?
是因为我没有实现异步任务吗?如果是这样,那怎么办?
这是我的代码:
package com.sara.facebookappl;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.facebook.android.Util;
public class MainActivity extends Activity implements OnClickListener, DialogListener {
Facebook fb;
ImageView button;
SharedPreferences sp;
TextView welcome;
Button post;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
post=(Button)findViewById(R.id.button1);
String APP_ID = getString(R.string.APP_ID);
fb= new Facebook(APP_ID);
sp =getPreferences(MODE_PRIVATE);
String access_token=sp.getString("access_token", null);
long expires=sp.getLong("access_expires", 0);
if (access_token !=null) {
fb.setAccessToken(access_token);
}
if(expires !=0) {
fb.setAccessExpires(expires);
}
button=(ImageView)findViewById(R.id.login);
button.setOnClickListener((OnClickListener) this);
updateButtonImage();
}
@SuppressWarnings("deprecation")
private void updateButtonImage() {
// TODO Auto-generated method stub
post.setVisibility(Button.VISIBLE);
button.setImageResource(R.drawable.com_facebook_loginbutton_blue);
//logout button
if (fb.isSessionValid()) {
button.setImageResource(R.drawable.com_facebook_loginbutton_blue);
// ^logout button
JSONObject obj=null;
URL img_url =null;
try {
String jsonUser= fb.request("me");
obj = Util.parseJson(jsonUser);
String id=obj.optString("id");
String name = obj.optString("name");
welcome.setText("Welcome, " + name);
}catch(FacebookError e) {
e.printStackTrace();
}catch (JSONException e) {
e.printStackTrace();
}catch (MalformedURLException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}else {
post.setVisibility(Button.VISIBLE);
button.setImageResource(R.drawable.com_facebook_loginbutton_blue);
}
}
@SuppressWarnings("deprecation")
public void buttonClicks(View v) {
switch (v.getId()) {
case R.id.button1:
//post
Bundle params= new Bundle();
params.putString("name", "User X");
params.putString("caption", "Rating");
params.putString("description", "User X Rated");
params.putString("link", "http://...");
fb.dialog(MainActivity.this, "feed", params, new Facebook.DialogListener() {
@Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
}
@Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
@Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
}
@Override
public void onCancel() {
// TODO Auto-generated method stub
}
});
break;
}
}
@SuppressWarnings("deprecation")
public void onClick(View v) {
if(fb.isSessionValid()) {
try {
fb.logout(getApplicationContext());
updateButtonImage();
//button will close our our session
}catch(MalformedURLException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
}else{
//login into facebook
fb.authorize(MainActivity.this, new String[] {"email"}, new Facebook.DialogListener() {
@Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "fbError", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "onError", Toast.LENGTH_SHORT).show();
}
@Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
Editor editor=sp.edit();
editor.putString("access_token", fb.getAccessToken());
editor.putLong("access_expires", fb.getAccessExpires());
editor.commit();
updateButtonImage();
}
@Override
public void onCancel() {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "onCancel", Toast.LENGTH_SHORT).show();
}
});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@SuppressWarnings("deprecation")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
fb.authorizeCallback(requestCode, resultCode, data);
}
@Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
}
@Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
}
@Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
@Override
public void onCancel() {
// TODO Auto-generated method stub
}
}
LogCat错误:
12-16 04:56:59.070: E/AndroidRuntime(822): FATAL EXCEPTION: main
12-16 04:56:59.070: E/AndroidRuntime(822): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sara.facebookappl/com.sara.facebookappl.MainActivity}: android.os.NetworkOnMainThreadException
12-16 04:56:59.070: E/AndroidRuntime(822): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.app.ActivityThread.access$600(ActivityThread.java:141)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.os.Handler.dispatchMessage(Handler.java:99)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.os.Looper.loop(Looper.java:137)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.app.ActivityThread.main(ActivityThread.java:5039)
12-16 04:56:59.070: E/AndroidRuntime(822): at java.lang.reflect.Method.invokeNative(Native Method)
12-16 04:56:59.070: E/AndroidRuntime(822): at java.lang.reflect.Method.invoke(Method.java:511)
12-16 04:56:59.070: E/AndroidRuntime(822): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
12-16 04:56:59.070: E/AndroidRuntime(822): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
12-16 04:56:59.070: E/AndroidRuntime(822): at dalvik.system.NativeStart.main(Native Method)
12-16 04:56:59.070: E/AndroidRuntime(822): Caused by: android.os.NetworkOnMainThreadException
12-16 04:56:59.070: E/AndroidRuntime(822): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
12-16 04:56:59.070: E/AndroidRuntime(822): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
12-16 04:56:59.070: E/AndroidRuntime(822): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
12-16 04:56:59.070: E/AndroidRuntime(822): at java.net.InetAddress.getAllByName(InetAddress.java:214)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:461)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
12-16 04:56:59.070: E/AndroidRuntime(822): at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
12-16 04:56:59.070: E/AndroidRuntime(822): at com.facebook.android.Util.openUrl(Util.java:219)
12-16 04:56:59.070: E/AndroidRuntime(822): at com.facebook.android.Facebook.requestImpl(Facebook.java:806)
12-16 04:56:59.070: E/AndroidRuntime(822): at com.facebook.android.Facebook.request(Facebook.java:732)
12-16 04:56:59.070: E/AndroidRuntime(822): at com.sara.facebookappl.MainActivity.updateButtonImage(MainActivity.java:83)
12-16 04:56:59.070: E/AndroidRuntime(822): at com.sara.facebookappl.MainActivity.onCreate(MainActivity.java:63)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.app.Activity.performCreate(Activity.java:5104)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
12-16 04:56:59.070: E/AndroidRuntime(822): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
12-16 04:56:59.070: E/AndroidRuntime(822): ... 11 more
12-16 04:56:59.090: D/dalvikvm(822): GC_CONCURRENT freed 150K, 9% free 2723K/2988K, paused 7ms+58ms, total 239ms
答案 0 :(得分:0)
是因为我没有实现异步任务吗?
是。查看LogCat并找到最低的“由...引起”,在这种情况下,它是NetworkOnMainThreadException。 documentation读取:
应用程序尝试在其主线程上执行网络操作时引发的异常。 ......见文件Designing for Responsiveness。
如果我们从LogCat的底部向上阅读,您会看到上次运行的代码及其上方的行是:
at com.facebook.android.Facebook.request(Facebook.java:732)
at com.sara.facebookappl.MainActivity.updateButtonImage(MainActivity.java:83)
第83行调用Facebook#request()
这是一个网络操作...创建一个自定义的AsyncTask然后将这一行及其所有支持代码移到它的doInBackground()
方法中:
JSONObject obj=null;
URL img_url =null;
try {
String jsonUser= fb.request("me");
obj = Util.parseJson(jsonUser);
String id = obj.optString("id");
String name = obj.optString("name");
}catch (FacebookError e) {
e.printStackTrace();
}catch (JSONException e) {
e.printStackTrace();
}catch (MalformedURLException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
除了行welcome.setText("Welcome, " + name);
。您无法在doInBackground()
中访问UI对象,如TextView。您需要将此代码放在onPostExecute()
中,如果您阅读了AsyncTask文档,您将了解它可以访问UI线程。
这听起来很复杂,但经过一些阅读和一些尝试,你会发现它并没有那么糟糕。如果你遇到困难,有很多例子可以帮助你。祝你好运!