Java postInvalidate()不使用非ui线程
我正在使用自定义视图绘制游戏内容,我使用xml布局中的按钮启用或禁用使用单独线程绘制特定内容(矩形)。我设法使线程运行,但我使用的postInvalidate()方法被忽略。我也尝试使用setWillNotDraw(false)。它不起作用。我压缩了代码,具体来说,在代码的哪一部分我有这个问题 activity_main.xmlJava postInvalidate()不使用非ui线程,java,android,multithreading,canvas,android-custom-view,Java,Android,Multithreading,Canvas,Android Custom View,我正在使用自定义视图绘制游戏内容,我使用xml布局中的按钮启用或禁用使用单独线程绘制特定内容(矩形)。我设法使线程运行,但我使用的postInvalidate()方法被忽略。我也尝试使用setWillNotDraw(false)。它不起作用。我压缩了代码,具体来说,在代码的哪一部分我有这个问题 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://s
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frm"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.temp.Cview
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/bMineDetector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="Lock" />
</RelativeLayout>
</FrameLayout>
在上面的类中,我设置了一个onClickListener,它根据按钮的状态帮助启动或停止一个单独的线程
Cview.java
package com.example.temp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class Cview extends View implements OnTouchListener,Runnable{
Boolean isRunning=false,isLockMode=false;
Context gameContext;
Thread myThread=null;
public Cview(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
gameContext=context;
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Log.d("INVALIDATE", "Invalidating");
isLockMode=((MainActivity)gameContext).lock;
if(isLockMode==true){
canvas.drawRect(100, 100, 300, 300, null);
//invalidate();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
while(isRunning){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
isLockMode=((MainActivity)gameContext).lock;
this.postInvalidate();
Log.d("THREAD", "isRunning="+isRunning+";;isLockMode="+isLockMode);
}
}
void onStart(){
isRunning=true;
myThread=new Thread(this);
myThread.start();
//Log.d("INVALIDATE", "onStart");
//postInvalidate();
}
void onPause(){
isRunning=false;
while(true){
try {
myThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
myThread=null;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return true;
}
}
请任何人帮助我。我需要在执行run方法后重新绘制画布。我已经考虑了几个月,而且我也是编程新手。因此,请指导我,并建议我是否有其他更好的方法来完成我需要的工作。谢谢。如中所述,从其他线程使用postInvalidate时可能会出现一些问题
我还没有测试过它,它不是很好,但它可以帮助您(而不是this.postInvalidate();
)
我刚刚遇到了完全相同的问题 我的解决方案是使用 onCreate()中的findViewById(),而不是调用构造函数 加 到您的XML,以及
v = (Cview) findViewById(R.id.custom_view);
调用onCreate()函数(并删除构造函数调用)
调用setContentView()后执行此操作
Android有无数类似这样的无声故障模式。我尝试过,但它不起作用。Invalidate被忽略:(
((MainActivity) gameContext).runOnUiThread(new Runnable() {
@Override
public void run() {
Cview.this.invalidate();
}
});
android:id="@+id/custom_view"
v = (Cview) findViewById(R.id.custom_view);