Changing image on Android thread

江枫思渺然 提交于 2021-01-28 10:07:41

问题


I've gone through stackoverflow and all the similar answers - but have found them not of use.

Can anyone please point out why this is not working? It should be simple: update the image every 6 seconds (will be every 3 mins but for testing I've put it as 6 seconds).

What the code does is - goes through each of the 4 images step by step but does not change the image. HOWEVER when it gets to the last image - it does change it(??).

Questions:

  1. What's wrong with this?
  2. Why would it only update the last image?
  3. If I start the code with just a "post" to the handler instead of a "postDelayed" - the tablet just stays with a black screen. Why do I have to start the code with a delay to make it work?

int currentIndex = 0;
boolean start = false;
ImageView descriptionImage;
private Runnable timerRunnable;
long startTime = 0;
private Handler handler;

int[] pictureIds = new int[]{R.drawable.hang, R.drawable.dog, R.drawable.coffee, R.drawable.about};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    pictureDescription = new ArrayList<String>();
    handler = new Handler(Looper.getMainLooper());
}

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_picture_test, container, false);
    descriptionImage = (ImageView) v.findViewById(R.id.iv_picture);

    return v;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    start();
}

private void start() {

    start = true;
    startTime = System.currentTimeMillis();
    loadImage();
    timerRunnable = new Runnable() {

        @Override
        public void run() {
            while (start) {
                long time = System.currentTimeMillis() - startTime;
                float mins = (float) time / (60 * 1000);
                if (mins >= 0.1f) {
                    startTime = System.currentTimeMillis();
                    if (currentIndex < pictureIds.length) {
                        currentIndex++;
                        loadImage();
                    }
                }
            }
        }
    };
    handler.postDelayed(timerRunnable, 1000);
}

private void loadImage() {
    getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (currentIndex < pictureIds.length) {
                descriptionImage.setImageResource(pictureIds[currentIndex]);
            } else {
                start = false; // finish
            }

        }
    });
}

Thanks!

EDIT: Doesn't work if I post it to the imageview thread either, instead of the handler.

descriptionImage.postDelayed(timerRunnable, 1000);


回答1:


What's wrong with this?

while the UI Thread is busy ( while (start) ) , waiting to your condition to became true ( if (mins >= 0.1f) { ), it can't take care of the rest (like drawing).

Why would it only update the last image?

because it can draw only when if (currentIndex < pictureIds.length) { is not true, start becomes false, and the UI thread can finally draw

If I start the code with just a "post" to the handler instead of a "postDelayed" - the tablet just stays with a black screen. Why do I have to start the code with a delay to make it work?

see point 1.

if you want to change your image every 3 seconds, you could keep using Handler#postDelayed. E.g.

start = true;
startTime = System.currentTimeMillis();
loadImage();
timerRunnable = new Runnable() {

    @Override
    public void run() {
        currentIndex = currentIndex++ % pictureIds.length;
        loadImage();
        handler.postDelayed(this, 3000);
    }
};
handler.postDelayed(timerRunnable, 3000);



回答2:


The problem you're facing is that your while loop is running on the main thread. This means the UI never has a chance to update until after the while loop ends (thus why you're only seeing the final image). Try this as your start function:

private void start() {

    timerRunnable = new Runnable() {

        @Override
        public void run() {
            if (currentIndex < pictureIds.length) {
                loadImage();
                currentIndex++;
                handler.postDelayed(timerRunnable, 6 * 1000);
            }
        }
    };
    handler.post(timerRunnable);
}


来源:https://stackoverflow.com/questions/44506961/changing-image-on-android-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!