Android 无法从异步任务内部触摸外部视图。。。但并非总是如此
我做了一个异步任务,应该编译一个TextView。这是对我所做工作的简短回顾。我删除了很多行,所以我希望我没有忘记任何东西Android 无法从异步任务内部触摸外部视图。。。但并非总是如此,android,Android,我做了一个异步任务,应该编译一个TextView。这是对我所做工作的简短回顾。我删除了很多行,所以我希望我没有忘记任何东西 public class MyClass extends RelativeLayout { private TextView messageTextView; public MyClass(Context context) { super(context); init(context); } public
public class MyClass extends RelativeLayout {
private TextView messageTextView;
public MyClass(Context context) {
super(context);
init(context); }
public MyClass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context); }
public MyClass(Context context, AttributeSet attrs) {
super(context, attrs);
init(context); }
private void init(Context context) {
createLayoutContent();
run();
}
private void createLayoutContent (Context context) {
this.setLayoutParams(new RelativeLayout.LayoutParams (RelativeLayout.LayoutParams.MATCH_PARENT, 0));
messageView = new TextView(context);
messageView.setText("test");
this.addView(messageView);
}
private void start() {
new AsyncTask<Void, String, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
String s_message = "test2";
messageView.setText(s_message); **// HERE IS WHERE THE ERROR IS //**
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
}
公共类MyClass扩展了RelativeLayout{
私有文本视图messageTextView;
公共MyClass(上下文){
超级(上下文);
init(上下文);}
公共MyClass(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
init(上下文);}
公共MyClass(上下文、属性集属性){
超级(上下文,attrs);
init(上下文);}
私有void init(上下文){
createLayoutContent();
run();
}
私有void createLayoutContent(上下文){
this.setLayoutParams(新的RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,0));
messageView=新文本视图(上下文);
messageView.setText(“测试”);
this.addView(messageView);
}
私有void start(){
新建异步任务(){
@凌驾
受保护的Void doInBackground(Void…参数){
试一试{
字符串s_message=“test2”;
messageView.setText(s_message);**//这里是错误所在//**
}捕获(格式错误){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}捕获(JSONException e){
e、 printStackTrace();
}
返回null;
}
}.execute();
}
}
之后,我将对象直接放在布局中:
<<...>MyClass
android:id="@+id/test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
现在的问题是,在一些应用程序上,这一点非常有效。一旦活动运行,setContentView()就会创建ui对象,一切正常。
在其他应用程序上,我不断收到一个错误,上面说“只有创建视图层次结构的原始线程才能接触其视图。”
我得到了这个错误,但我不明白为什么在一些应用程序上它工作良好。。。
更奇怪的是,有一次我碰巧发现,通常出现错误的应用程序突然开始工作,然后在两次正确运行后返回错误
这太奇怪了
我知道可能细节不足以检测错误,所以请原谅,但是我检查了所有我能想到的细节,我没有发现它工作时与不工作时的显著差异。也许更专业的眼睛可以发现一些东西,解释一些东西,或者建议我在哪里调试。
有人能帮我吗
非常感谢。我不知道为什么有时它会起作用。但每次都应该失败。 如果Android系统决定在UI线程中运行您的后台线程代码,那么它可能会起作用 以下是解决问题的方法: 将“触摸视图”内容移动到
onPostExecution()
或onProgressUpdate()
。
UI意味着只能从UI线程内进行触摸。AsyncTask有助于非常方便地完成此任务。除了doInBackground()
之外,所有AsyncTask的
方法都在UI线程上运行
因此,从不直接从doInBackground()
更改视图
private void start(){
新建异步任务(){
@凌驾
受保护字符串doInBackground(无效…参数){
试一试{
字符串s_message=“test2”;
返回s_消息;
}捕获(格式错误){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}捕获(JSONException e){
e、 printStackTrace();
}
返回null;
}
@凌驾
受保护的void onPostExecute(字符串s){
messageView.setText;
}
}.execute();
}
ooh!!onPostExecute拯救了我的一天!非常感谢。关于它为什么起作用。。。我不知道,但我确信它在市场上目前在线的一些应用程序上有效。。。只是为了确保我无论如何都会编辑它们。除了doInBackground()
以外的任何方法。因为此方法正在后台线程中运行。
private void start() {
new AsyncTask<Void, String, String>() {
@Override
protected String doInBackground(Void... params) {
try {
String s_message = "test2";
return s_message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String s) {
messageView.setText(s);
}
}.execute();
}