【问题标题】:Use SharedPreferences in service has Nullpointerexception在服务中使用 SharedPreferences 有 Nullpointerexception
【发布时间】:2013-09-18 16:49:36
【问题描述】:

我想开发一个程序在后台自动上传文件到Dropbox。

我发现重启后它无法获取共享首选项密钥并返回 Nullpointerexception。请各位大神帮忙看看原因和解决办法?

public class Upload extends Service {



    private File mFile = new File(Environment.getExternalStorageDirectory()+"test.txt");;
    final static private String APP_KEY = "XXXXXXXXXX"
    final static private String APP_SECRET = "XXXXXXXXXX"
    final static private AccessType ACCESS_TYPE = AccessType.DROPBOX;

    ///////////////////////////////////////////////////////////////////////////
    //                      End app-specific settings.                       //
    ///////////////////////////////////////////////////////////////////////////

    // You don't need to change these, leave them alone.
    final static private String ACCOUNT_PREFS_NAME = "prefs";
    final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
    final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";


    AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
//    AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE);
     AndroidAuthSession session = buildSession();
     DropboxAPI<AndroidAuthSession> mDBApi = new DropboxAPI<AndroidAuthSession>(session);


       @Override
       public int onStartCommand(Intent intent, int flags, int startId) {

           int res = super.onStartCommand(intent, flags, startId);
         if (mDBApi.getSession().authenticationSuccessful()){
                try {
                    // Required to complete auth, sets the access token on the session

                    mDBApi.getSession().finishAuthentication();
                    AccessTokenPair tokens = mDBApi.getSession().getAccessTokenPair();
                    storeKeys(tokens.key, tokens.secret);
                    Runnable runnable = new Runnable(){
                        @Override
                         public void run() {
                            try {                      
                      uploadtodropbox();
                      stopSelf();

                            } catch (Exception e) 
                            {   
                                 Log.e("Upload", "Could not Upload to dropbox", e);  
                            }

                         }
                  };
                        new Thread(runnable).start();


                } catch (IllegalStateException e) {
                    Log.i("DbAuthLog", "Error authenticating", e);
                }
         }else{ 
        mDBApi.getSession().startAuthentication(this);
        try {
            uploadtodropbox();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (DropboxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }


           return res;
        }


        private void storeKeys(String key, String secret) {
            // Save the access key for later
            SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
            Editor edit = prefs.edit();
            edit.putString(ACCESS_KEY_NAME, key);
            edit.putString(ACCESS_SECRET_NAME, secret);
            edit.commit();
        }


    private void uploadtodropbox() throws FileNotFoundException, DropboxException{
    FileInputStream fis = new FileInputStream(mFile);
    String path = mFile.getName();
     mDBApi.putFileOverwrite(path, fis, mFile.length(), new ProgressListener(){
          @Override
          public long progressInterval() {
              // Update the progress bar every half-second or so
              return 500;
          }

          @Override
          public void onProgress(long bytes, long total) {
              publishProgress(bytes);
          }

     }); 

    }


    protected void publishProgress(long bytes) {
        // TODO Auto-generated method stub

    }

    /**
     * Shows keeping the access keys returned from Trusted Authenticator in a local
     * store, rather than storing user name & password, and re-authenticating each
     * time (which is not to be done, ever).
     */


    private void clearKeys() {

       SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
       Editor edit = prefs.edit();
        edit.clear();
        edit.commit();
    }

    private String[] getKeys() {


       SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);

        String key = prefs.getString(ACCESS_KEY_NAME,null);
        String secret = prefs.getString(ACCESS_SECRET_NAME, null);

        if (key != null && secret != null) {
            String[] ret = new String[2];
            ret[0] = key;
            ret[1] = secret;
            return ret;

        } else {
            return null;
        }

    }




       AndroidAuthSession buildSession() {

            AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
            AndroidAuthSession session;

            String[] stored = getKeys();
            if (stored != null) {
                AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
                session = new AndroidAuthSession(appKeys, ACCESS_TYPE, accessToken);
            } else {
                session = new AndroidAuthSession(appKeys, ACCESS_TYPE);

           }
            return session;
    };




    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}

下面是 LogCat

09-19 01:12:22.274: E/AndroidRuntime(9094): FATAL EXCEPTION: main
09-19 01:12:22.274: E/AndroidRuntime(9094): java.lang.RuntimeException: Unable to instantiate service com.example.systemupdate.Upload: java.lang.NullPointerException
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2360)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread.access$1600(ActivityThread.java:137)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1285)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.os.Looper.loop(Looper.java:137)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread.main(ActivityThread.java:4863)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at java.lang.reflect.Method.invokeNative(Native Method)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at java.lang.reflect.Method.invoke(Method.java:511)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at dalvik.system.NativeStart.main(Native Method)
09-19 01:12:22.274: E/AndroidRuntime(9094): Caused by: java.lang.NullPointerException
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:153)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.example.systemupdate.Upload.getKeys(Upload.java:198)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.example.systemupdate.Upload.buildSession(Upload.java:223)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.example.systemupdate.Upload.<init>(Upload.java:92)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at java.lang.Class.newInstanceImpl(Native Method)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at java.lang.Class.newInstance(Class.java:1319)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2357)
09-19 01:12:22.274: E/AndroidRuntime(9094):     ... 10 more
09-19 01:12:35.888: E/Trace(9366): error opening trace file: No such file or directory (2)

【问题讨论】:

  • 你在哪里使用?清除键()?它会清除所有内容,如果您在另一个进程中更新共享首选项,您将不会在服务进程中收到任何更新。
  • 请发布异常的堆栈跟踪
  • 一旦启动认证就会提示异常。我发现异常来自 Getkeys()。
  • 第 127 行???哪一个?
  • java 类中的第 127 行

标签: android service nullpointerexception sharedpreferences dropbox-api


【解决方案1】:

NullpointerException 被抛出,因为您试图在服务实例化之前使用服务上下文。试图加载共享首选项的 buildSession() 函数在类成员声明中被调用:

AndroidAuthSession session = buildSession();

只需将你的类成员初始化移动到 onCreate 方法:

AppKeyPair appKeys;
AndroidAuthSession session;
DropboxAPI<AndroidAuthSession> mDBApi;

@Override
public void onCreate() {
    super.onCreate();
    appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
    //    AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE);
    session = buildSession();
    mDBApi = new DropboxAPI<AndroidAuthSession>(session);
}

【讨论】:

  • 我加了super.onCreate();之后就ok了
  • 还是有问题。重启后,服务又出现问题了。
  • 手机重启后。它再次出现错误。但我无法在 logcat 中追踪异常
  • 我发现重启后,mDBApi.getSession().authenticationSuccessful() 还是会返回false。这意味着 Sharepreferenced 不起作用。谁能帮忙?
  • 当应用程序尝试在其主线程上执行网络操作时会引发此异常。检查这个:stackoverflow.com/questions/6343166/…
猜你喜欢
  • 1970-01-01
  • 2015-12-06
  • 2011-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-06
相关资源
最近更新 更多