在 Android 线程中更改图像
Changing image on Android thread
我浏览了 Whosebug 和所有类似的答案 - 但发现它们没有用。
谁能指出为什么这不起作用?它应该很简单:每 6 秒更新一次图像(将每 3 分钟更新一次,但为了测试我将其设置为 6 秒)。
代码的作用是 - 逐步检查 4 张图像中的每一张,但不更改图像。然而,当它到达最后一张图片时 - 它确实改变了它(??)。
问题:
- 这有什么问题?
- 为什么只更新最后一张图片?
- 如果我在处理程序中仅使用 "post" 而不是 "postDelayed" 来启动代码 - 平板电脑只会保持黑屏。为什么我必须延迟启动代码才能使其工作?
</p>
<pre><code>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
}
}
});
}
谢谢!
编辑:如果我 post 将它发送到 imageview 线程而不是处理程序,则不起作用。
descriptionImage.postDelayed(timerRunnable, 1000);
What's wrong with this?
虽然 UI 线程正忙 (while (start)
),等待您的条件变为真 (if (mins >= 0.1f) {
),但它无法处理其余的事情(例如绘图).
Why would it only update the last image?
因为只有if (currentIndex < pictureIds.length) {
不为真才能绘制,所以start
变为假,UI线程终于可以绘制
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?
参见第 1 点。
如果你想每 3 秒更改一次图像,你可以继续使用 Handler#postDelayed。例如
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);
您面临的问题是您的 while 循环在主线程上 运行。这意味着 UI 在 while 循环结束之前永远没有机会更新(因此你只能看到最终图像)。试试这个作为你的 start
功能:
private void start() {
timerRunnable = new Runnable() {
@Override
public void run() {
if (currentIndex < pictureIds.length) {
loadImage();
currentIndex++;
handler.postDelayed(timerRunnable, 6 * 1000);
}
}
};
handler.post(timerRunnable);
}
我浏览了 Whosebug 和所有类似的答案 - 但发现它们没有用。
谁能指出为什么这不起作用?它应该很简单:每 6 秒更新一次图像(将每 3 分钟更新一次,但为了测试我将其设置为 6 秒)。
代码的作用是 - 逐步检查 4 张图像中的每一张,但不更改图像。然而,当它到达最后一张图片时 - 它确实改变了它(??)。
问题:
- 这有什么问题?
- 为什么只更新最后一张图片?
- 如果我在处理程序中仅使用 "post" 而不是 "postDelayed" 来启动代码 - 平板电脑只会保持黑屏。为什么我必须延迟启动代码才能使其工作?
</p>
<pre><code>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
}
}
});
}
谢谢!
编辑:如果我 post 将它发送到 imageview 线程而不是处理程序,则不起作用。
descriptionImage.postDelayed(timerRunnable, 1000);
What's wrong with this?
虽然 UI 线程正忙 (while (start)
),等待您的条件变为真 (if (mins >= 0.1f) {
),但它无法处理其余的事情(例如绘图).
Why would it only update the last image?
因为只有if (currentIndex < pictureIds.length) {
不为真才能绘制,所以start
变为假,UI线程终于可以绘制
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?
参见第 1 点。
如果你想每 3 秒更改一次图像,你可以继续使用 Handler#postDelayed。例如
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);
您面临的问题是您的 while 循环在主线程上 运行。这意味着 UI 在 while 循环结束之前永远没有机会更新(因此你只能看到最终图像)。试试这个作为你的 start
功能:
private void start() {
timerRunnable = new Runnable() {
@Override
public void run() {
if (currentIndex < pictureIds.length) {
loadImage();
currentIndex++;
handler.postDelayed(timerRunnable, 6 * 1000);
}
}
};
handler.post(timerRunnable);
}