NotifyBuilder

时间:2015-12-10 10:39:59

标签: android android-asynctask handler runtimeexception android-looper

我有这个代码,我想要有两个不同的动作,我想要显示一个经典通知来打开MainActivity,另一个通知做LogoutTask,但我这个java.lang.RuntimeException:无法创建未调用Looper.prepare()

的线程内部处理程序

我告诉你,我的NotificationBuilder,AsyncTask和错误。

通知方法

private void sendNotification(final String message) {
    if (!message.contains("password")) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_kleim_letter)
                .setContentTitle(TITLE_NAME)
                .setContentText(message)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        Random random = new Random();
        int m = random.nextInt(9999 - 1000) + 1000;
        notificationManager.notify(m, notificationBuilder.build());
    } else {
        DoLogoutTask doLogoutTask = new DoLogoutTask(getBaseContext());
        doLogoutTask.execute();
        Intent intent = new Intent(MyGcmListenerService.this, Login.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(MyGcmListenerService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(MyGcmListenerService.this)
                .setSmallIcon(R.drawable.ic_stat_kleim_letter)
                .setContentTitle(TITLE_NAME)
                .setContentText(message)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notificationBuilder.build());
    }
}

ASYNCTASK

public class DoLogoutTask extends AsyncTask<Void, Void, Boolean> {
SoapPrimitive resultString;
String response;
SharedPreferences mSharedPreferences;
SharedPreferences.Editor editor;
Context context;
ProgressDialog progressDialog;
public DoLogoutTask(Context context) {
    this.context = context;
    this.progressDialog = new ProgressDialog(context, R.style.progress_dialog_kleim);
}
@Override
protected void onPreExecute() {
    this.progressDialog.show();
    this.progressDialog.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
    this.progressDialog.setCancelable(false);
    this.progressDialog.getWindow().setGravity(Gravity.BOTTOM);
    this.progressDialog.setIndeterminate(true);
}
@Override
protected Boolean doInBackground(Void... params) {
    return doLogout();
}
@Override
protected void onPostExecute(Boolean result) {
    if (progressDialog != null && progressDialog.isShowing())
        progressDialog.dismiss();
}
public Boolean doLogout() {
    Boolean isLoggedOut = null;
    mSharedPreferences = context.getSharedPreferences(PreferencesUtility.MYPREFERENCES, Context.MODE_PRIVATE);
    String URL = URL;
    String METHOD = METHOD;
    String NAMESPACE = NAMESPACE;
    String SOAP_ACTION = ACTION;
    String idCliente = mSharedPreferences.getString(PreferencesUtility.IDCLIENTE, PreferencesUtility.VALUENOTFOUND);
    String regid = mSharedPreferences.getString(PreferencesUtility.REGID, PreferencesUtility.VALUENOTFOUND);
    JSONObject parent = new JSONObject();
    JSONObject logout = new JSONObject();
    JSONArray jsonArray = new JSONArray();
    try {
        logout.put("idCliente", idCliente);
        logout.put("regid", regid);
        parent.put("cliente", jsonArray);
        jsonArray.put(logout);
        String parentString = parent.toString();
        PropertyInfo paramPI = new PropertyInfo();
        paramPI.setName("infoCliente");
        paramPI.setValue(parentString);
        paramPI.setType(String.class);
        SoapObject request = new SoapObject(NAMESPACE, METHOD);
        request.addProperty(paramPI);
        SoapSerializationEnvelope soapSerializationEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        soapSerializationEnvelope.dotNet = true;
        soapSerializationEnvelope.setOutputSoapObject(request);
        HttpTransportSE transportSE = new HttpTransportSE(URL);
        transportSE.call(SOAP_ACTION, soapSerializationEnvelope);
        resultString = (SoapPrimitive) soapSerializationEnvelope.getResponse();
        response = resultString.toString();
        isLoggedOut = !response.contains("error");
    } catch (JSONException e) {
        e.printStackTrace();
    } catch (HttpResponseException e) {
        e.printStackTrace();
    } catch (SoapFault soapFault) {
        soapFault.printStackTrace();
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return isLoggedOut;
    }
}

ERROR

  

12-10 11:09:53.486 19138-19390 / it.penta.kleim E / AndroidRuntime:致命异常:AsyncTask#3                                                                   过程:it.penta.kleim,PID:19138                                                                   java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序                                                                       在android.os.Handler。(Handler.java:200)                                                                       在android.os.Handler。(Handler.java:114)                                                                       在android.app.Dialog。(Dialog.java:119)                                                                       在android.app.AlertDialog。(AlertDialog.java:200)                                                                       在android.app.AlertDialog。(AlertDialog.java:196)                                                                       在android.app.ProgressDialog。(ProgressDialog.java:82)                                                                       at it.penta.kleim.sixteen.retro_asynctasks.DoLogoutTask。(DoLogoutTask.java:44)                                                                       at it.penta.kleim.sixteen.retro_gcm.MyGcmListenerService.sendNotification(MyGcmListenerService.java:107)                                                                       at it.penta.kleim.sixteen.retro_gcm.MyGcmListenerService.onMessageReceived(MyGcmListenerService.java:75)                                                                       在com.google.android.gms.gcm.GcmListenerService.zzq(未知来源)                                                                       在com.google.android.gms.gcm.GcmListenerService.zzp(未知来源)                                                                       在com.google.android.gms.gcm.GcmListenerService.zzo(未知来源)                                                                       在com.google.android.gms.gcm.GcmListenerService.zza(未知来源)                                                                       在com.google.android.gms.gcm.GcmListenerService $ 1.run(未知来源)                                                                       在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)                                                                       at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:588)                                                                       在java.lang.Thread.run(Thread.java:818)

1 个答案:

答案 0 :(得分:0)

您的sendNotification方法由执行onMessageReceived的线程池中的线程调用,因此您无法触及视图。为了触摸视图,你应该从主线程获得一个Handler(你可以使用Looper.getMainLooper())。 请检查http://developer.android.com/training/multiple-threads/communicate-ui.html

这是一个快速示例:

Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
    @Override
    public void run() {
        //do stuff on the main thread
    }
});

您应该在run()方法

中移动与对话框相关的所有内容