android - 线程错误

标签 android multithreading android-thread

我得到一些错误。我今天真的解决不了 :( 我在 FillData() 方法中将 ID 数据设置为 lblID 后出错。它正确设置了 ID 数据,但 lblTitle 和 lblPrice 总是返回错误,如“只有创建 View 层次结构的原始线程可以触摸它的 View ”和程序停止运行。

注意:这不是我的原始代码。我只是将它最小化以便更容易理解,当然它会给出与下面代码相同的错误。无论如何,在 FillData() 方法中,我从 wcf 服务获取数据并正确返回数据。我试过 runonuithread 但它没有任何意义。此外,如果我在线程外编写代码,它不会填充控件。因为它最初是从 wcf 服务获取数据的。

public class MainActivity extends AppCompatActivity {
LinearLayout lytData;
TextView lblTitle, lblID, lblPrice;

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

    lytData = (TextView)findViewById(R.id.lytNewData);
    lblID = (TextView)findViewById(R.id.lblID);
    lblTitle = (TextView)findViewById(R.id.lblTitle); 
    lblPrice = (TextView)findViewById(R.id.lblPrice); 
    new Thread() {
        public void run() {
            FillData();
        }
    }.start();

    lytData.setOnTouchListener(new OnCustomTouchListener (context) {
        @Override
        public void ToLeft() {
            new Thread() {
                public void run() {
                    FillData();
                }
            }.start();
        }

        @Override
        public void ToRight() {
            new Thread() {
                public void run() {
                    FillData();
                }
            }.start();
        }
    });
}

void FillData() {
   lblID.setText("aaa");
   lblTitle.setText("aaa");
   lblPrice.setText("aaa");
}

最佳答案

问题是您试图在另一个线程中更新 UI,但只能在 UI 线程中更新 UI。如果您只是按照代码显示的那样更新了 UI,那么您应该从辅助线程中删除 FillData 的调用,如果您在 FillData() 中进行大量加载,则使用辅助线程,否则您最好直接在 UI 线程中更新 UI: 所以不要这样做:

   new Thread() {
      public void run() {
         FillData();
         pd.cancel();
      }
    }.start();

只需调用 FillData();在新线程之外。

您还可以调用 runOnUiThread 将更新带到 ui 线程:

getActivity().runOnUiThread(new Runnable() {
    public void run() {
        FillData();
    }
});

如果您在 FillData 中的代码与重载代码混合在一起,那么您可以将 runOnUiThread 方法带到 FillData 中,并仅将 UI 更新代码移动到 runOnUiThread.

如果您仍想保持代码不变,您可以像这样从辅助线程“发布”更改:

viewElement.post(new Runnable() {
        public void run() {
            //update UI
        }
    });
}

viewElement 是从 View 扩展的任何 UI 元素。

关于android - 线程错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50137388/

相关文章:

Android 服务 : Bind on demand vs. 在#onCreate() 上绑定(bind)

java - 什么时候是终止线程的最佳时机以及如何终止线程?

java - 我应该扩展哪个类,AcionBar 还是 ActionBarImpl?

android - 不显示警报对话框

java - AchartEngine 获取触摸点位置

java - 对象的成员不需要 volatile 而只需要原始成员吗?

ios - 使用 NSOperation 和 NSOperationQueue 的好习惯是什么?

c++ - 使用 SendMessage() 多线程

android - 如何停止android应用程序kill上的所有服务,线程,卸载库

android - 如何正确处理 Room 线程