Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/192.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 线程错误_Android_Multithreading_Android Thread - Fatal编程技术网

Android 线程错误

Android 线程错误,android,multithreading,android-thread,Android,Multithreading,Android Thread,我犯了一些错误。今天我真的解决不了这个问题:(我在FillData()方法中将ID数据设置为lblID后出现错误。它正确设置了ID数据,但lblTitle和lblPrice总是返回错误,如“只有创建视图层次结构的原始线程才能接触其视图”,程序停止运行 注意:这不是我的原始代码。我只是将其最小化以便于理解,当然它会产生与下面代码相同的错误。无论如何,在FillData()中方法我从wcf服务获取数据,它会正确返回数据。我尝试runonuithread,但没有任何意义。此外,如果我在线程之外编写代码

我犯了一些错误。今天我真的解决不了这个问题:(我在FillData()方法中将ID数据设置为lblID后出现错误。它正确设置了ID数据,但lblTitle和lblPrice总是返回错误,如“只有创建视图层次结构的原始线程才能接触其视图”,程序停止运行

注意:这不是我的原始代码。我只是将其最小化以便于理解,当然它会产生与下面代码相同的错误。无论如何,在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元素。如果需要从线程以任何方式更改UI,应使用runonuithread()并在你传递给它的runnable中执行你的更改,我会让你搜索谷歌上有很多这样的例子。downvoter请对社区有建设性的态度,解释为什么你第一次否决了downvotedI,因为你的答案是“从你的线程中进行修改”wich是无用的,如果OP在线程中这样做,他必须有这样做的理由,然后您添加了runonuithread()解决方案,wich对我来说是好的解决方案,因此我删除了我的投票。如果您检查OP FillData();方法他们没有理由在另一个线程中这样做,他们当然可能有原因,但从他们发布的内容来看,原因并不清楚,因此我们可以建议他们什么是最好的方法。你的工作不是推断他可能需要什么或可能不需要什么,因为这不是这里提出的问题,你可以建议se,但这也不是你写它的方式的一个建议,我不会更进一步,因为我相信你明白我的观点,并且争论这是没有用的。Awwww我明白了。那么你应该把RunonUI放在里面,只阅读更新UI的代码或使用“post”方法。对不起,我以为你只有UI更新代码