即使我的代码中没有错误,Facebook Android应用程序仍然崩溃。为什么?

时间:2012-12-16 00:25:07

标签: android facebook

如果您导入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

1 个答案:

答案 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线程。

这听起来很复杂,但经过一些阅读和一些尝试,你会发现它并没有那么糟糕。如果你遇到困难,有很多例子可以帮助你。祝你好运!