无限循环 - 延迟 - 单独的线程

Posted

技术标签:

【中文标题】无限循环 - 延迟 - 单独的线程【英文标题】:infinite loop - delay - separate threads 【发布时间】:2018-06-25 08:18:26 【问题描述】:

我正在 android 上开发一个应用程序。

我有一个片段问题,可以在下面找到代码。

这个想法是让一个图像视图在一个无限循环中显示一个图片列表。为了实现这一点,我创建了一个新的 Thread,以免阻塞 UI Thread。使用 while (0

一个 Handler 用于处理切换图片之间的 10 秒延迟。最后,另一个 runnable 负责发布到 UI 线程。

这似乎是一种完成工作的非常复杂的方法,有人用过更简单的代码吗?

最重要的是,在我的代码的某个地方,有一个错误。我看不到它,有人吗?

这是我的代码。

public class SecAct_Foto_Fragment extends Fragment 

    int counter = 0;
    View rootView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 

        rootView = inflater.inflate(R.layout.sec_act_photo_layout, container, false);

        return rootView;
    

    Thread myThread = new Thread(new Runnable() 
        @Override
        public void run() 
            while (0 < 5) 

                //so far it loops only once
                //you start with run_rocks and but_left
                final ImageView pic_view = (ImageView) rootView.findViewById(R.id.foto_groot);
                final ImageView three_but = (ImageView) rootView.findViewById(R.id.knoppen);

                //create a runnable for the picture view
                pic_view.post(new Runnable() 
                    @Override
                    public void run() 
                        //every 10 seconds, switch picture and button fragment
                        if (counter == 0) 
                            final Handler handler0 = new Handler();
                            handler0.postDelayed(new Runnable() 
                                @Override
                                public void run() 
                                    pic_view.post(new Runnable() 
                                        @Override
                                        public void run() 
                                            pic_view.setImageResource(R.drawable.run_mount);
                                        
                                    );
                                    counter = 1;
                                
                            , 10000L);
                         else if (counter == 1) 
                            final Handler handler1 = new Handler();
                            handler1.postDelayed(new Runnable() 
                                @Override
                                public void run() 
                                    pic_view.post(new Runnable() 
                                        @Override
                                        public void run() 
                                            pic_view.setImageResource(R.drawable.run_away);
                                        
                                    );
                                    counter = 2;
                                
                            , 10000L);
                         else 
                            final Handler handler2 = new Handler();
                            handler2.postDelayed(new Runnable() 
                                @Override
                                public void run() 
                                    pic_view.post(new Runnable() 
                                        @Override
                                        public void run() 
                                            pic_view.setImageResource(R.drawable.run_rocks);
                                        
                                    );
                                    counter = 0;
                                
                            , 10000L);
                        
                    
                );

                myThread.start();
            
        
    );

【问题讨论】:

所以你只是想在循环中有一些延迟来改变图片? 是的,完全正确。处理程序似乎是解决延迟的最佳方法,并且需要一个单独的线程来发布到 UI 线程。不是吗? 是的,不过还有其他方法,发帖分享一下 您可以使用 Alaa M. 的答案,***.com/questions/7161500/… 这篇文章也将帮助您添加动画 【参考方案1】:
     private class AsyncQueryRun extends AsyncTask 
    @Override
            protected Object doInBackground(Object[] objects) 
                for (...)
                     ////do what you want


                    runOnUiThread(new Runnable() 
                            @Override
                               public void run() 
                           ///do what you want to be handled by UI thread
                           );
                  SystemClock.sleep(60); ////wait as long as you want in mili sec.
               
    
    @Override
            protected void onPostExecute(Object o) 
                 
    

【讨论】:

【参考方案2】:

您可以通过以下方式使用Handler:

        final ImageView pic_view = (ImageView) rootView.findViewById(R.id.foto_groot);

        private int animationCounter = 1;
        private Handler imageSwitcherHandler;
        imageSwitcherHandler = new Handler(Looper.getMainLooper());
        imageSwitcherHandler.post(new Runnable() 
            @Override
            public void run() 
                switch (animationCounter++) 
                    case 1:
                        pic_view.setImageResource(R.drawable.run_mount);

                        break;
                    case 2:
                        pic_view.setImageResource(R.drawable.run_mount2);

                        break;
                    case 3:
                        pic_view.setImageResource(R.drawable.run_mount3);
                        break;
                
                animationCounter %= 4;
                if(animationCounter == 0 ) animationCounter = 1;

                imageSwitcherHandler.postDelayed(this, 3000);
            
        );

【讨论】:

用图片换图片,你想要的【参考方案3】:

我决定尝试@NehaK 的解决方案并使用 ImageSwitcher 视图。

在 XML 中添加了以下代码..

   <ImageSwitcher
        android:id="@+id/foto_groot_imageswitch"
        android:layout_
        android:layout_
        app:srcCompat="@drawable/run_rocks"
    />

然后在我的 Fragment 中使用它..

    public class SecAct_Foto_Fragment extends Fragment 

    int counter = 0;
    View rootView;
    private ImageSwitcher pic_image_switch;
    private Handler pic_image_switch_handler;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 

        rootView = inflater.inflate(R.layout.sec_act_photo_layout, container, false);

        /*Animation anim_in = AnimationUtils.loadAnimation(getActivity(), R.anim.enter_from_left);
        pic_image_switch.setInAnimation(anim_in);*/

        //pic_image_switch = new ImageSwitcher(getActivity());
        pic_image_switch = (ImageSwitcher) rootView.findViewById(R.id.foto_groot_imageswitch);

        pic_image_switch.setFactory(new ViewSwitcher.ViewFactory() 
            @Override
            public View makeView() 
                ImageView imageView = new ImageView(getActivity());
                imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
                return imageView;
            
        );

        pic_image_switch_handler = new Handler(Looper.getMainLooper());

        pic_image_switch_handler.post(new Runnable() 
            @Override
            public void run() 
                switch (counter) 
                    case 0:
                        pic_image_switch.setImageResource(R.drawable.run_mount);
                        break;
                    case 1:
                        pic_image_switch.setImageResource(R.drawable.run_away);
                        break;
                    case 2:
                        pic_image_switch.setImageResource(R.drawable.run_rocks);
                        break;
                
                counter += 1;
                if (counter == 3) 
                    counter = 0;
                
                pic_image_switch.postDelayed(this, 1000);
            
        );

        return rootView;
    

【讨论】:

以上是关于无限循环 - 延迟 - 单独的线程的主要内容,如果未能解决你的问题,请参考以下文章

每个循环可能会或可能不会运行 CDialog 的无限线程

Javascript无延迟播放无限循环音频文件

启动和停止无限循环

术语,概念

无限循环的线程是不是会导致 CPU 过多

具有无限循环和 thread.sleep 高 CPU 使用率的多个线程