0

我想开发一个程序在后台自动将文件上传到 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)
4

1 回答 1

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);
}
于 2013-09-18T17:44:19.583 回答