1

にデータを保存するアプリケーションがありますSharedPreferences。この制御データはサーバーと同期され、ユーザーがアプリケーションにログインすると、AsyncTask. SharedPreferences取得したデータを再度保存しようとしていますが、 java.lang.ExceptionInInitializerError.

これはAsyncTaskコードです:

public class RetrieveLogTask extends AsyncTask<Void, Void, Boolean> {
    private String errorMessage;

    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            String controlRow = NetworkUtilities.getData();

            if(controlRow != null){
                LogHandler.restoreControls(LoginActivity.this, controlRow);                 
                return true;                        
            }
        } catch (AuthenticationException e) {
            errorMessage = e.getMessage();
        } catch (Exception e) {
            errorMessage = e.getMessage();
        }

        return false;
    }

    @Override
    protected void onPostExecute(final Boolean success) {
        mRetrieveTask = null;

        if (success) {              
            createAccountAndFinish(true);
        } 
        else{
            Log.d("LoginActivity", errorMessage);
            askRetry();
        }
    }

    @Override
    protected void onCancelled() {
        mRetrieveTask = null;
        showProgress(false);
    }
}

そして、これはエラーを引き起こしている LogHandler クラスの関数です:

public static void restoreControls(Context ctx, String controlRow){
    String[] controls = controlRow.split(LogHandler.FILE_COLUMN_SEPARATOR_ESCAPED);
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
    Editor editor = prefs.edit();

    editor.putString(TODService.PREFS_KEY_ARRAY_ICONTROLS, controlRow); // ERROR HERE

    editor.commit();
}

エラーの原因となっている行はputString呼び出しです。controlRow は null でも空でもなく、editor は null ではありません。

これはログ出力です:

04-19 10:59:50.900: E/AndroidRuntime(16609): FATAL EXCEPTION: AsyncTask #2
04-19 10:59:50.900: E/AndroidRuntime(16609): java.lang.RuntimeException: An error occured while executing doInBackground()
04-19 10:59:50.900: E/AndroidRuntime(16609):    at android.os.AsyncTask$3.done(AsyncTask.java:278)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at java.lang.Thread.run(Thread.java:856)
04-19 10:59:50.900: E/AndroidRuntime(16609): Caused by: java.lang.ExceptionInInitializerError
04-19 10:59:50.900: E/AndroidRuntime(16609):    at com.timeondriver.tod.log.LogHandler.restoreControls(LogHandler.java:835)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at com.timeondriver.tod.authenticate.LoginActivity$RetrieveLogTask.doInBackground(LoginActivity.java:328)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at com.timeondriver.tod.authenticate.LoginActivity$RetrieveLogTask.doInBackground(LoginActivity.java:1)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at android.os.AsyncTask$2.call(AsyncTask.java:264)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-19 10:59:50.900: E/AndroidRuntime(16609):    ... 5 more
04-19 10:59:50.900: E/AndroidRuntime(16609): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-19 10:59:50.900: E/AndroidRuntime(16609):    at android.os.Handler.<init>(Handler.java:121)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at com.timeondriver.tod.TODService$1.<init>(TODService.java:513)
04-19 10:59:50.900: E/AndroidRuntime(16609):    at com.timeondriver.tod.TODService.<clinit>(TODService.java:513)
04-19 10:59:50.900: E/AndroidRuntime(16609):    ... 10 more

誰でもそれを修正する方法を知っていますか??

ありがとう!

[編集]

私はいくつかのコードを追加します:

private void askRetry() {
    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(LoginActivity.this);

    alertDialogBuilder
    .setTitle(getResources().getString(R.string.title_error_retry))
    .setMessage(getResources().getString(R.string.message_error_retry))
    .setCancelable(false)

    .setPositiveButton(getResources().getString(R.string.retry)
            ,new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog,int id) {
            mRetrieveTask = new RetrieveLogTask();
            mRetrieveTask.execute((Void) null);
        }
    })

    .setNegativeButton(getResources().getString(R.string.alert_cancel)
            ,new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog,int id) {
            showProgress(false);    
        }
    })
    ; // Fin alertDialogBuilder

    AlertDialog alertDialog = alertDialogBuilder.create();
    alertDialog.show();     
}

private void createAccountAndFinish(boolean logRetrieved){
    showProgress(false);

    // Create the local account.
    Account account = new Account(mPhone, ACCOUNT_TYPE);
    Bundle user_data = new Bundle();
    try{
        mAccountManager.addAccountExplicitly(account, mPassword, user_data);
    }catch(Exception e){
        e.printStackTrace();
        return;
    }

    // Set account's additional data and finish the activity.
    final Intent intent = new Intent();
    intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mPhone);
    intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
    intent.putExtra(AccountManager.KEY_PASSWORD, mPassword);
    intent.putExtra(AccountManager.KEY_AUTHTOKEN, mAuthToken);
    intent.putExtra(AccountManager.KEY_BOOLEAN_RESULT, true);
    LoginActivity.this.setAccountAuthenticatorResult(intent.getExtras());
    setResult(RESULT_OK, intent);        

    Intent i = new Intent(this, Main.class);
    startActivity(i);
    LoginActivity.this.finish();
}

TODService.java:513 には、Handler 宣言があります。

private static Handler mHandler = new Handler(){
    ...
}

[/編集]

4

1 に答える 1

1

ExceptionInInitializerError - 静的初期化子で予期しない例外が発生したことを通知します。静的初期化子または静的変数の初期化子の評価中に例外が発生したことを示すために、ExceptionInInitializerError がスローされます。

java.lang.RuntimeException: Looper.prepare() を呼び出していないスレッド内でハンドラを作成できません

UIから更新するために何かをしているようNon-UI threadです。つまり、バックグラウンド ワーカー スレッドから

LogHandler.restoreControls(LoginActivity.this, controlRow);でこのステートメントを呼び出す必要がありますonPostExecute();

したがって、編集したクラスは次のようになります

public class RetrieveLogTask extends AsyncTask<Void, Void, Boolean>
{
    private String errorMessage;

    @Override
    protected Sring doInBackground(Void... params)
    {
        String controlRow = null;
        try
        {
            controlRow = NetworkUtilities.getData();
        }
        catch ( AuthenticationException e )
        {
            errorMessage = e.getMessage();
        }
        catch ( Exception e )
        {
            errorMessage = e.getMessage();
        }
        return controlRow;
    }

    @Override
    protected void onPostExecute(final String controlRow)
    {
        mRetrieveTask = null;
        if ( controlRow != null )
        {
            LogHandler.restoreControls(LoginActivity.this, controlRow);
            createAccountAndFinish(true);
        }
        else
        {
            Log.d("LoginActivity", errorMessage);
            askRetry();
        }
    }

    @Override
    protected void onCancelled()
    {
        mRetrieveTask = null;
        showProgress(false);
    }
}
于 2013-04-19T09:26:02.370 に答える