我目前有Android活动管理一些本地存储的RSS源。在此活动中,这些订阅源通过私有类在其自己的线程中更新。我还试图包含一个“更新”图标,该图标在此线程运行时以RotateAnimation
旋转。
动画本身可以工作,但在线程运行时不起作用,尽管日志条目表明正在执行代码。我怀疑这是由于线程不完全安全,占用了大部分CPU时间。但是,我想知道是否有更好的方法来实现这一目标。
按下按钮调用函数updateAllFeeds()
。这是相关的代码:
/**
* Gets the animation properties for the rotation
*/
protected RotateAnimation getRotateAnimation() {
// Now animate it
Log.d("RSS Alarm", "Performing animation");
RotateAnimation anim = new RotateAnimation(359f, 0f, 16f, 21f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(700);
return anim;
}
/**
* Animates the refresh icon with a rotate
*/
public void setUpdating() {
btnRefreshAll.startAnimation(getRotateAnimation());
}
/**
* Reverts the refresh icon back to a still image
*/
public void stopUpdating() {
Log.d("RSS Alarm", "Stopping animation");
btnRefreshAll.setAnimation(null);
refreshList();
}
/**
* Updates all RSS feeds in the list
*/
protected void updateAllFeeds() {
setUpdating();
Updater updater = new Updater(channels);
updater.run();
}
/**
* Class to update RSS feeds in a new thread
* @author Michael
*
*/
private class Updater implements Runnable {
// Mode flags
public static final int MODE_ONE = 0;
public static final int MODE_ALL = 1;
// Class vars
Channel channel;
ArrayList<Channel> channelList;
int mode;
/**
* Constructor for singular update
* @param channel
*/
public Updater(Channel channel) {
this.mode = MODE_ONE;
this.channel = channel;
}
/**
* Constructor for updating multiple feeds at once
* @param channelList The list of channels to be updated
*/
public Updater(ArrayList<Channel> channelList) {
this.mode = MODE_ALL;
this.channelList = channelList;
}
/**
* Performs all the good stuff
*/
public void run() {
// Flag for writing problems
boolean write_error = false;
// Check if we have a singular or list
if(this.mode == MODE_ONE) {
// Updating one feed only
int updateStatus = channel.update(getApplicationContext());
// Check for error
if(updateStatus == 2) {
// Error - show dialog
write_error = true;
}
}
else {
// Iterate through all feeds
for(int i = 0; i < this.channelList.size(); i++) {
// Update this item
int updateStatus = channelList.get(i).update(getApplicationContext());
if(updateStatus == 2) {
// Error - show dialog
write_error = true;
}
}
}
// If we have an error, show the dialog
if(write_error) {
runOnUiThread(new Runnable(){
public void run() {
showDialog(ERR_SD_READ_ONLY);
}
});
}
// End updater
stopUpdating();
} // End run()
} // End class Updater
(我知道updateStatus == 2
位是不好的做法,这是我打算收拾的下一件事之一。)
非常感谢任何帮助,非常感谢提前。
答案 0 :(得分:0)
在单独的线程中运行updater runnable。进行以下更改。
protected void updateAllFeeds() {
setUpdating();
new Thread( new Updater(channels)).start();
}
在stopUpdating()
阻止中致电runOnUiThread
。
private class Updater implements Runnable {
.........
.........
.........
public void run() {
.........
.........
// End updater
runOnUiThread(new Runnable(){
public void run() {
stopUpdating();
}
});
} // End run()
} // End class Updater
答案 1 :(得分:0)
将影响用户界面的任何内容移至自己的Runnable
,然后使用按钮发布
btnRefreshAll.post(new StopUpdating());
答案 2 :(得分:0)
昨晚我设法使用Android的AsyncTask课程来完成这项工作。它实现起来非常简单,但缺点是我必须编写一个类来更新单个feed,另一个用于更新所有feed。以下是一次更新所有Feed的代码:
private class MassUpdater extends AsyncTask<ArrayList<Channel>, Void, Void> {
@Override
protected Void doInBackground(ArrayList<Channel>... channels) {
ArrayList<Channel> channelList = channels[0];
// Flag for writing problems
boolean write_error = false;
// Iterate through all feeds
for(int i = 0; i < channelList.size(); i++) {
// Update this item
int updateStatus = channelList.get(i).update(getApplicationContext());
if(updateStatus == FileHandler.STATUS_WRITE_ERROR) {
// Error - show dialog
write_error = true;
}
}
// If we have an error, show the dialog
if(write_error) {
runOnUiThread(new Runnable(){
public void run() {
showDialog(ERR_SD_READ_ONLY);
}
});
}
return null;
}
protected void onPreExecute() {
btnRefreshAll.setAnimation(getRotateAnimation());
btnRefreshAll.invalidate();
btnRefreshAll.getAnimation().startNow();
}
protected void onPostExecute(Void hello) {
btnRefreshAll.setAnimation(null);
refreshList();
}
}
感谢您的回答。 userSeven7s的回复也很有道理,所以如果我遇到AsyncTask的任何问题,我可能会将其用作备份。