Java 方法必须从UI线程调用,当前推断的线程为工作线程

Java 方法必须从UI线程调用,当前推断的线程为工作线程,java,android,multithreading,android-fragments,canvas,Java,Android,Multithreading,Android Fragments,Canvas,我试图在画布上画圆圈。目前,我可以在点击按钮时执行此操作,但在加载片段时也需要执行相同的操作。下面是我的片段代码 public class StepTwentyOneFragment extends Fragment { private CanvasView customCanvas; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle save

我试图在画布上画圆圈。目前,我可以在点击按钮时执行此操作,但在加载
片段时也需要执行相同的操作。下面是我的
片段
代码

public class StepTwentyOneFragment extends Fragment {

    private CanvasView customCanvas;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.step21_fragment, container, false);
        customCanvas=(CanvasView)v.findViewById(R.id.signature_canvas);

        final Button button1=(Button)v.findViewById(R.id.step18button1);


        float radius=(customCanvas.getCanvasWidth()/2) - ((customCanvas.getCanvasWidth()/2)/100)*60;
        new MyAsyncTask(customCanvas).execute();

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(v.getId()==R.id.step18button1){

                    float radius=(customCanvas.getCanvasWidth()/2) - ((customCanvas.getCanvasWidth()/2)/100)*60;
                    customCanvas.drawCircle(radius);
                    Log.d("An_Width", "" + customCanvas.getCanvasWidth());
                    Log.d("An_Height" ,""+ customCanvas.getCanvasHeight());

                    v.setBackgroundResource(R.drawable.button_border_5);
                    button1.setTextColor(Color.WHITE);


                }
            }
        });






        return v;
    }

    public static StepTwentyOneFragment newInstance() {

        StepTwentyOneFragment f = new StepTwentyOneFragment();
        Bundle b = new Bundle();

        f.setArguments(b);

        return f;
    }


    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(isVisibleToUser) {
            Activity a = getActivity();
            if(a != null) a.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
    }

    public class MyAsyncTask extends AsyncTask<Void, Void, Void> {

        CanvasView myTaskView;

        MyAsyncTask(CanvasView v){
            myTaskView = v;
        }

        @Override
        protected Void doInBackground(Void... arg0) {

            myTaskView.drawCircle(150);
            return null;
        }

    }

}
然而,在我的
片段中,在
MyAsyncTask
内,它显示了必须从UI线程调用的错误
方法drawCircle,当前推断的线程是代码行
myTaskView.drawCircle(150)的worker


如何修复此问题?

如果在doInBackground()中实现,则无法在UI线程上显示任何内容。它是用于后台任务的。要更新UI,必须在postexecute()中实现方法

阅读有关AsyncTask的更多信息:

明确你的概念,那么使用AsynTask就更容易了

异步任务的基本结构:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }
私有类下载文件任务扩展异步任务{
受保护的长doInBackground(URL…URL){
int count=url.length;
长totalSize=0;
for(int i=0;i
如果在doInBackground()中实现,则无法在UI线程上显示任何内容。它是用于后台任务的。要更新UI,必须在postexecute()中实现方法

阅读有关AsyncTask的更多信息:

明确你的概念,那么使用AsynTask就更容易了

异步任务的基本结构:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }
私有类下载文件任务扩展异步任务{
受保护的长doInBackground(URL…URL){
int count=url.length;
长totalSize=0;
for(int i=0;i
myTaskView.drawCircle(150)在从非UI线程调用drawcircle之前导致问题的行@ρƏ∑ρєK:对,如何修复?。直接从
onCreate
调用该部分没有任何作用,因此我认为加载fragmnet时,它必须在该线程内才能画出圆圈?将其移动到onPostExecute方法@ρ魈σѕρєK:谢谢,该方法位于何处?障碍,我的问题是为什么要使用
异步任务
?我认为如果你只是为了调用
myTaskView.drawCircle(150),就不需要使用它。以及
AsyncTask
类中可用的onPostExecute方法,所以只需以与您对
doInBackground
在从非UI线程调用drawcircle之前导致问题的行@ρƏ∑ρєK:对,如何修复?。直接从
onCreate
调用该部分没有任何作用,因此我认为加载fragmnet时,它必须在该线程内才能画出圆圈?将其移动到onPostExecute方法@ρ魈σѕρєK:谢谢,该方法位于何处?障碍,我的问题是为什么要使用
异步任务
?我认为如果你只是为了调用
myTaskView.drawCircle(150),就不需要使用它。和
AsyncTask
类中可用的onPostExecute方法,所以只需以与您对
doInBackground
所做相同的方式重写它,该
onPostExecute
方法在哪里?@Barrier请参见编辑的答案。如果要显示任何工作进度,onProgressUpdate()是可选的。我应该传递哪些参数?我现在没有参数all@Barrier如果没有参数,则应将Void作为参数传递。请按照说明进行准备。圆圈尚未绘制此
onPostExecute
方法在哪里?@Barrier请参见编辑的答案。如果要显示任何工作进度,onProgressUpdate()是可选的。我应该传递哪些参数?我现在没有参数all@Barrier如果没有参数,则应将Void作为参数传递。请按照说明进行准备。圆圈还没有画出来