Android Jobservice уничтожается

android job-scheduling

1249 просмотра

1 ответ

228 Репутация автора

Я устроил Jobservice, чтобы сделать некоторые вещи. Для теста я запускаю его каждые тридцать секунд. Чтобы найти проблему, я сократил сервис, чтобы ничего не делать (!). Я знаю, что работа может быть остановлена ​​системой; если метод onStopJob возвращает true, он будет перезапущен. Это происходит и работает хорошо, хотя мне интересно, как часто и в какое время (среди ночи, пока телефон просто лежит на столе!).
Чтобы проверить все это, я использую SharedPreferences, отслеживая остановки и перезапуски.
Однако я узнал, что работа не только прекращается, но иногда и полностью разрушается. Затем я включил процедуру перезапуска в методе OnDestroy. Это не работает. Работа перезапускается, но немедленно уничтожается снова. Итак, у меня есть несколько вопросов:
Почему он разрушен в первую очередь?
И почему нельзя перезапустить его?
И что я могу сделать, чтобы сделать его более стабильным?
Пробовал на Galaxy S4 под Android 5.0.1 и XPeria Z2 под 6.0
Скомпилирован под MinSDK 5.0, TargetSDK 6.0.
Вот код моего JobSchedulerService:

public class  JobSchedulerService extends JobService implements
    DataApi.DataListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener 
{

private boolean stoppedByUser = false;
public DateFormat formatter;
String stoptimeText;
public GregorianCalendar apptTime;
public Context myCnt;

@Override
public boolean onStartJob(JobParameters params){
        doJob(this);
        jobFinished(params, false );
    return true;
}

public void doJob(Context context){
    myCnt = context;
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(myCnt);
    SharedPreferences.Editor editor = prefs.edit();
    stoptimeText = prefs.getString("stopped","not yet stopped");
    editor.putString("started", "Job was running at " + timeNow());
    editor.apply();
    // do something here
}

@Override
public boolean onStopJob(JobParameters params){
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    stoppedByUser = prefs.getBoolean("stoppedByUser", false);
    SharedPreferences.Editor editor = prefs.edit();
    stoptimeText += "Job stopped autom. at " + timeNow();
    editor.putString("stopped", stoptimeText);
    editor.apply();
    if (stoppedByUser){
        stoppedByUser = false;
        editor.putBoolean("stoppedByUser", false);
        stoptimeText += "OnStopJob called by user-stop at " + timeNow();
        editor.putString("stopped", stoptimeText);
        editor.apply();
        return false;
    }
    else return true;
}

@Override
public void onDestroy() {
    super.onDestroy();
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    stoppedByUser = prefs.getBoolean("stoppedByUser", false);
    SharedPreferences.Editor editor = prefs.edit();
    stoptimeText += "Job was destroyed at "+ timeNow();
    editor.putString("stopped", stoptimeText);
    editor.apply();
    if (!stoppedByUser){
        JobInfo.Builder builder = new JobInfo.Builder(1,
                new ComponentName(getPackageName(), JobSchedulerService.class.getName()));
        builder.setPeriodic(30 * 1000);
        builder.setPersisted(true);
        stoptimeText += "Job rest. after dstr. at " + timeNow();
        editor.putString("stopped", stoptimeText);
        editor.putString("started", "Auto update started after destroy! Check if really running!");
        editor.apply();
    }
    else {
        stoptimeText += "OnDestroy called by user-stop at " + timeNow();
        editor.putString("stopped", stoptimeText);
        editor.apply();
    }
}

public String timeNow(){
    apptTime = (GregorianCalendar) GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
    formatter = new SimpleDateFormat("EEE, dd./HH:mm", Locale.ENGLISH);
    formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
    return formatter.format(apptTime.getTimeInMillis());
}

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
}

@Override
public void onConnected(Bundle connectionHint) {
}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
}

@Override
public void onConnectionSuspended(int arg0) {
}
}

И вот мой MainActivity (сокращенно):

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    myCnt = this;

    initGoogleApiClient();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);

    tabLayout = (TabLayout) findViewById(R.id.tabs);
    if (tabLayout != null)
        tabLayout.setupWithViewPager(viewPager);

    mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);

//.......

public void startJob(){
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString("started", "auto updates started by user!");
    editor.putBoolean("stoppedByUser", false);
    editor.apply();

    JobSchedulerService jss = new JobSchedulerService(); // used to "first run" the job, so there is no waiting time for the user
    jss.doJob(myCnt);

    JobInfo.Builder builder = new JobInfo.Builder(1,
            new ComponentName(getPackageName(), JobSchedulerService.class.getName()));
    builder.setPeriodic(30 * 1000);
    builder.setPersisted(true);

    if (mJobScheduler.schedule(builder.build()) <= 0) {
        Toast.makeText(MainActivity.this, "Failure starting Jobservice!", Toast.LENGTH_LONG).show();
    }
}
Автор: tomseitz Источник Размещён: 18.07.2016 08:45

Ответы (1)


1 плюс

228 Репутация автора

После долгих исследований я обнаружил, что проблема заключается в следующем:

// do something here  

У меня была Async Task. Однако, по словам Google, это работает только в потоке пользовательского интерфейса (см .: https://developer.android.com/reference/android/os/AsyncTask.html ).
Наличие этого в моем JobSchedulerService вызвало его уничтожение через некоторое время.
Сейчас я использую (обычный) отдельный поток, чтобы «сделать что-то» в Сервисе, и это работает.

Автор: tomseitz Размещён: 13.09.2016 08:05
Вопросы из категории :
32x32