2011-09-02 97 views
1

我目前有一個Android活動,用於管理一些本地存儲的RSS源。在此活動中,這些供稿通過私人課程在其自己的線索中更新。我還試圖在此線程運行時包含一個「RotateAnimation」旋轉的「更新」圖標。Android:正在運行線程以防止啓動動畫

雖然日誌條目聲明代碼正在執行,但該動畫獨立運行,但在線程運行時不起作用。我懷疑這是由於線程不是完全安全的,佔用了大部分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

只是爲了澄清:您不能嘗試從除主應用程序線程以外的線程更新UI。 'AsyncTask'通過在主線程上執行'onPostExecute'和'onPreExecute'來處理。通過使用'Handler'和'Message'將你的UI更新邏輯發佈到主線程,你可以得到相同的結果。 – Matthias

回答

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 
0

移動任何影響UI關進自己Runnable,然後用你的按鈕它張貼

btnRefreshAll.post(new StopUpdating());

0

我設法使用Android的AsyncTask類這方面的工作最後一夜。實現起來非常簡單,但缺點是我必須編寫一個類來更新單個提要,另一個用於更新所有提要。這裏是一次更新所有飼料的代碼:

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的任何問題時。