【问题标题】:CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its viewsCalledFromWrongThreadException:只有创建视图层次结构的原始线程才能接触其视图
【发布时间】:2011-12-03 00:35:04
【问题描述】:

我正在IntentService 中的数据库中进行操作,并在Activity 中显示CustomProgressBar,但我还想显示百分比值。因此,为此我在 IntentService 中获取百分比值,并在 Activity 中的静态方法中设置该值。但是出现了错误:

CalledFromWrongThreadException:只有创建的原始线程 视图层次结构可以触及其视图。

我不想在 AsyncTask 中执行此操作,因为我不想阻塞 UI,所以我正在使用 IntentService。

这是我的做法。

MyIntentService.java

公共类 MyIntentService 扩展 IntentService { @覆盖 公共无效 onHandleIntent(意图意图) { 更新数据库(); }

public void updateDatabase()
{
    resetPercentage(cursor.getCount * 2) 
    do
    {
      // do operation for updating the database

      // here I update the view everytime a new item is inserted in DB.
      int updatedReturn = MyActivity.updatePercentageValue(percentage()); 
    }
    while(...)
}

public void resetPercentage(int elementsNum)
{
mUpdatePercentage = 0;

mMaxItems = elementsNum;
}

public int incrementPercentageCounter()
{
return ++mPercentageCounter;
}

public int percentage()
{
    int value = (mPercentageCounter/mMaxItems)*100;

return (value > 100) ? 100 : value;
}
}

MyActivity.java

public class MyActivity extends Activity
{
     private TextView mMyTextView;

     @Override
     public void onCreate(Bundle bundle)
     {
         super.onCreate(bundle);
         mMyTextView = (TextView) findViewById(R.id.textview);
     }

     public static int updatePercentageValue(int percentageValue)
     {
         mMyTextView.setText("" + percentageValue + " %");

         return 1;
     }
}

关于如何解决此问题或使用我的 IntentService 执行此操作的任何想法,以便 UI 不会被阻塞。

Obs:我也想继续使用IntentService,因为很多事情都已经完成了,我不想从头再来。

谢谢!

【问题讨论】:

  • 您在此处的活动代码似乎不完整或与您所拥有的不同。 mMyTextView 应该是与mPercentageValueTextView 相同的变量吗?那应该是静态变量吗?你真的应该避免对这种事情使用静态访问器。这不是一个好主意。

标签: android


【解决方案1】:

AsyncTask 不会阻塞 UI。您可能应该使用它。你试图做的事情正是它的好处。 AsyncTask 不需要存在于您的 Activity 之外,它是短暂的工作(相对而言),您的工作需要更新此 UI。在这里,AsyncTask 似乎比 Service 更合适。

【讨论】:

    【解决方案2】:

    在异步任务中做事是为了不阻塞 UI 线程。它甚至有一个 on progress 方法,可以在更新 UI 时准确地完成您想要做的事情。鉴于您不想这样做,但您需要查看运行方法。

    查看这段代码,我对它的工作原理有些困惑,因为您正在访问静态方法中的成员变量。

    【讨论】:

    • 在我调用 IntentService 的 AsyncTask 内部是个好主意吗?
    • 它不会伤害任何东西,但正如上面的答案所述,服务并不是您真正想要的,但它应该可以正常工作。在取得一些进展后,您可以告诉 Android 您有一些进展要报告 - 我忘记了他的方法名称,但请检查文档中的 AsyncTask 和该方法,然后使用 UI 线程调用 onProgressDisplay 以便您可以更新 UI。
    • 我只是想把控制代码和视图代码分开。但是我在 Asynctask 中调用 IntentService 我要创建另一个线程,对吗?但是 IntentService 在工作完成后会自行停止,对吗??
    • 从 AsyncTask 调用 IntentService 无济于事。您仍然会遇到同样的问题,即弄清楚如何将您的进度从 IntentService 传达给 AsyncTask。重构真的没那么难。花点时间以正确的方式去做。
    • 我在我的 Activity 类中创建了一个 AsyncTask 并在 doInBackground() 方法中调用了控制器类中的另一个方法来执行所有操作,并不断调用 Activity 中的静态方法来更新值在屏幕上,但同样的错误仍然存​​在。会是什么?谢谢!
    猜你喜欢
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    相关资源
    最近更新 更多