簡體   English   中英

Android 應用程序在將通知與 JobScheduler 一起使用時崩潰

[英]Android app crashes when using Notification with JobScheduler

我最近一直試圖讓應用程序每 5 秒顯示一次通知,即使它出於測試目的而關閉,所以我使用 JobService 來做到這一點:


public class Job1 extends JobService {

    private boolean cancelled  = false;
    public static final String tag = "Job";
    private int id = 0;

    private void createChannel(String id, CharSequence name, int imp) {
           NotificationChannel channel = new NotificationChannel(id, name ,  imp );
           NotificationManager nm = getSystemService(NotificationManager.class);
           nm.createNotificationChannel(channel);      
    }

    private void display(int id , CharSequence channel_id, String content, String title , Context ctx){

        createChannel((String)channel_id , channel_id , NotificationManager.IMPORTANCE_HIGH);

        NotificationCompat.Builder nb = new NotificationCompat.Builder(ctx, (String) channel_id)
                .setSmallIcon(R.drawable.ic_work_black_24dp)
                .setContentText(content)
                .setContentTitle(title)
                .setPriority(NotificationCompat.PRIORITY_MAX);


        NotificationManagerCompat nmc = NotificationManagerCompat.from(ctx);
        nmc.notify(id , nb.build() );
      }

    @Override
    public boolean onStartJob(JobParameters params) {
        Log.i(tag, "Job has been started");
        Job(params);

        return true;
    }

    private void Job(JobParameters params){


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    Log.i(tag, "Job is Running");
                   ///////////////////////////////////////////////////
                    //the crash begin here.

                    display(id++ , "channel1" , "Description" , "title" , this);
                    ////////////////////////////////////////////////////////////////

                    try {

                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }).start();

        //jobFinished(params , true);
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        Log.i(tag, "Job has been cancelled");
        cancelled = true;
        return true;
    }
}

調用作業的代碼:

ComponentName cname = new ComponentName(this, Job1.class);
            JobInfo jinfo = new JobInfo.Builder(1, cname)
                    .setRequiresCharging(false)
                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
                    .setPersisted(true)
                    .build();

            JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
            int result = scheduler.schedule(jinfo);
            if (result == JobScheduler.RESULT_SUCCESS) {
                Log.i("job", "scheduled");
            } else {
                Log.i("job", "failed");
            }

當然,我還添加了具有 AndroidManifest.xml 權限的服務名稱

  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

 <service android:name=".Job1"
            android:permission="android.permission.BIND_JOB_SERVICE" />

當我嘗試單獨使用通知 function 時,它可以完美地工作,例如只需一個按鈕即可使用它,當我刪除在Job中調用display function 的行時,工作工作,但是當我使用通知時,它會崩潰整個應用程序,那么可能是什么問題?

看了logcat,又仔細閱讀,終於找到了解決辦法

主要問題來自該JobService內部的線程本身,當我嘗試發出新通知時,應用程序因以下信息而崩潰:

java.lang.RuntimeException: Can't create handler inside thread Thread[Thread-2,5,main] that has not called Looper.prepare()

解決方案是創建一個新線程 Class 並調用Looper.prepare()

所以新的線程代碼將是這個 class:

public class TestThread extends Thread{

    private int id = 0;

    private Context ctx;

    public TestThread(Context ctx){
        this.ctx = ctx;
    }

    public void run(){

        //this line has solved the issue
        Looper.prepare();

        while(true){

            Log.i("Thread" , "Thread is currently running in background :)");

            // my notifciation class
            (new Notifications()).displayNot(id++ , "channel6", "Content" , "title" , ctx);

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

現在我們從工作中使用這個 class,在我的情況下,在Job function 中:

private void Job(JobParameters params){

        Thread thread = new TestThread(this);
        thread.start();

        if(!thread.isAlive()){
            jobFinished(params , true);
        }

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM