Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.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
Java postInvalidate()不使用非ui线程_Java_Android_Multithreading_Canvas_Android Custom View - Fatal编程技术网

Java postInvalidate()不使用非ui线程

Java 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布局中的按钮启用或禁用使用单独线程绘制特定内容(矩形)。我设法使线程运行,但我使用的postInvalidate()方法被忽略。我也尝试使用setWillNotDraw(false)。它不起作用。我压缩了代码,具体来说,在代码的哪一部分我有这个问题

activity_main.xml

<?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);