gpt4 book ai didi

java - 计时器导致 ViewRootImpl$CalledFromWrongThreadException?

转载 作者:太空宇宙 更新时间:2023-11-04 10:46:28 25 4
gpt4 key购买 nike

我有一种感觉是我的计时器导致了这次崩溃。奇怪的是我似乎无法在模拟器中重现它,但我的 Play 控制台崩溃报告告诉我用户不断遇到此崩溃:

android.view.ViewRootImpl$CalledFromWrongThreadException: 
at android.view.ViewRootImpl.checkThread (ViewRootImpl.java:7988)
at android.view.ViewRootImpl.invalidateChildInParent (ViewRootImpl.java:1392)
at android.view.ViewGroup.invalidateChild (ViewGroup.java:5426)
at android.view.View.invalidateInternal (View.java:14959)
at android.view.View.invalidate (View.java:14923)
at android.view.View.invalidate (View.java:14907)
at android.widget.TextView.checkForRelayout (TextView.java:8624)
at android.widget.TextView.setText (TextView.java:5137)
at android.widget.TextView.setText (TextView.java:4962)
at android.widget.TextView.setText (TextView.java:4937)
at com.kjdion.smoketracker.MainActivity$1.run (MainActivity.java:97)
at java.util.TimerThread.mainLoop (Timer.java:555)
at java.util.TimerThread.run (Timer.java:505)

这是我的MainActivity代码:

package com.kjdion.smoketracker;

import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import com.facebook.stetho.Stetho;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;

import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {

long longLast;
boolean timerStarted = false;
TextView sinceView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

MobileAds.initialize(this, "ca-app-pub-4097235499795154~8279081984");
AdView mAdView = findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);

//Stetho.initializeWithDefaults(this);
setViews();
}

public void startLogActivity(View view) {
Intent intent = new Intent(this, LogActivity.class);
startActivity(intent);
}

public void startChartActivity(View view) {
Intent intent = new Intent(this, ChartActivity.class);
startActivity(intent);
}

public void startHealthActivity(View view) {
Intent intent = new Intent(this, HealthActivity.class);
startActivity(intent);
}

@Override
public void onResume() {
super.onResume();
setViews();
}

public void setViews() {
// init vars
long date = Helpers.currentTime();
String na = getResources().getString(R.string.text_na);
String sinceLast = na;
String longestGone = na;
String smokedToday = na;
String lowestDay = na;
sinceView = findViewById(R.id.sinceLast);
TextView longestView = findViewById(R.id.longestGone);
TextView todayView = findViewById(R.id.smokedToday);
TextView lowestView = findViewById(R.id.lowestDay);

// grab db
LogDatabaseHelper logDatabaseHelper = new LogDatabaseHelper(this);
SQLiteDatabase database = logDatabaseHelper.getWritableDatabase();
Cursor cursor;

// since last
cursor = database.rawQuery("" +
"SELECT * " +
"FROM " + LogDatabaseHelper.TABLE_NAME + " " +
"ORDER BY id DESC " +
"LIMIT 1", null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();

longLast = (date - cursor.getLong(cursor.getColumnIndex("date"))) * 1000;
sinceLast = Helpers.toDuration(longLast);

if (!timerStarted) {
timerStarted = true;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// update since last text every second
sinceView.setText(Helpers.toDuration(longLast));
longLast = longLast + 1000;
}
}, 0, 1000);
}
}
cursor.close();

// longest gone
cursor = database.rawQuery("" +
"SELECT * FROM " + LogDatabaseHelper.TABLE_NAME + " " +
"ORDER BY length DESC " +
"LIMIT 1" +
"", null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();

long longGone = cursor.getLong(cursor.getColumnIndex("length")) * 1000;
if (longGone > 0) {
longestGone = Helpers.toDuration(longGone);
}
}
cursor.close();

// smoked today
cursor = database.rawQuery("" +
"SELECT sum(`amount`) as `sum` " +
"FROM " + LogDatabaseHelper.TABLE_NAME + " " +
"WHERE date(`date`, 'unixepoch') = date("+date+", 'unixepoch')" +
"", null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();

if (!cursor.isNull(cursor.getColumnIndex("sum"))) {
smokedToday = Helpers.toFraction(cursor.getDouble(cursor.getColumnIndex("sum")), 1000);
}
}
cursor.close();

// lowest day
cursor = database.rawQuery("" +
"SELECT sum(`amount`) as `sum` " +
"FROM " + LogDatabaseHelper.TABLE_NAME + " " +
"WHERE date(`date`, 'unixepoch') < date("+date+", 'unixepoch')" +
"GROUP BY date(`date`, 'unixepoch') " +
"ORDER BY `sum` ASC " +
"LIMIT 1" +
"", null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();

if (!cursor.isNull(cursor.getColumnIndex("sum"))) {
lowestDay = Helpers.toFraction(cursor.getDouble(cursor.getColumnIndex("sum")), 1000);
}
}
cursor.close();
database.close();

// set view text
sinceView.setText(sinceLast);
longestView.setText(longestGone);
todayView.setText(smokedToday);
lowestView.setText(lowestDay);
}
}

是计时器造成的吗?我必须将计时器放在 UI 线程上吗?

最佳答案

TimerTask 在工作线程(非 UI 线程)上执行。您的 UI (sinceView) 必须从主 (UI) 线程访问。 Activity 中有一个辅助方法可以执行此操作: runOnUiThread .

MainActivity.this.runOnUiThread(new Runnable() {
sinceView.setText(Helpers.toDuration(longLast));
});

关于java - 计时器导致 ViewRootImpl$CalledFromWrongThreadException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48365896/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com