2011-09-02 12 views
1

현재 로컬로 저장된 일부 RSS 피드를 관리하는 Android 활동이 있습니다. 이 액티비티에서는 이러한 피드가 전용 클래스를 통해 자체 스레드에서 업데이트됩니다. 또한이 스레드가 실행되는 동안 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(); 
} 

전화 runOnUiThread 블록 stopUpdating(). Runnable 자체로 UI를 영향을 내가 안드로이드의 AsyncTask 클래스를 사용하여이 작업을 지난 밤 얻을 수 있었다

btnRefreshAll.post(new StopUpdating());

0

이동 아무것도. 개별 피드를 업데이트하기위한 클래스 하나와 모든 피드를 업데이트하기위한 클래스를 작성해야한다는 단점이 있지만 구현하기가 놀랍도록 쉬웠습니다. 한 번에 모든 피드를 업데이트하는 코드는 다음과 같습니다.

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를 사용하여 문제가 발생하면 백업으로 사용할 수 있습니다.

0

다음 버튼으로 게시

private class Updater implements Runnable { 
    ......... 
    .........  
    ......... 
    public void run() { 
     ......... 
     ......... 

     // End updater 
     runOnUiThread(new Runnable(){ 
       public void run() { 
        stopUpdating(); 
       } 
      }); 

    } // End run() 
} // End class Updater