2014-09-19 104 views
1

我在嘗試在Android中執行重複性任務時遇到了一些問題。下面是我如何填充我的列表視圖:Android重複執行任務在後臺運行

public View getView(int position, View convertView, ViewGroup parent) { 
    String recurID; 
    if (convertView == null) { 

     convertView = inflater.inflate(R.layout.recur_listview_row, null); 

     viewHolder = new ViewHolder(); 
     viewHolder.txt_ddate = (TextView) convertView.findViewById(R.id.txtDisplayRecurDate); 
     viewHolder.txt_damount = (TextView) convertView.findViewById(R.id.txtDisplayRecurAmount); 
     viewHolder.txt_dfrequency = (TextView) convertView.findViewById(R.id.txtDisplayFrequency); 

     convertView.setTag(viewHolder); 

    } else { 
     viewHolder = (ViewHolder) convertView.getTag(); 
    } 

    recurID = _recurlist.get(position).getRecurringID(); 
    // Format and calculate the next payment date based on frequency 
    try { 
     String dateStr = _recurlist.get(position).getRecurringStartDate(); 
     String frequencyStr = _recurlist.get(position).getFrequency(); 

     Calendar cal = Calendar.getInstance(); 
     cal.setTime(dateFormat.parse(dateStr)); 

     if (frequencyStr.equals("Daily")) { 
      cal.add(Calendar.DAY_OF_MONTH, 1); 
      viewHolder.txt_ddate.setText("Next Payment On: " + dateFormat.format(cal.getTimeInMillis())); 
      cal.add(Calendar.DAY_OF_MONTH, -1); 
     } else if (frequencyStr.equals("Weekly")) { 
      cal.add(Calendar.WEEK_OF_YEAR, 1); 
      viewHolder.txt_ddate.setText("Next Payment On: " + dateFormat.format(cal.getTimeInMillis())); 
      cal.add(Calendar.WEEK_OF_YEAR, -1); 
     } 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 

    viewHolder.txt_dfrequency.setText(_recurlist.get(position).getFrequency().trim()); 

    if (_recurlist.get(position).getRecurringType().equals("W")) { 
     viewHolder.txt_damount.setTextColor(Color.rgb(180, 4, 4)); 
     viewHolder.txt_damount.setText("Credit $ " + amount); 
    } else if (_recurlist.get(position).getRecurringType().equals("D")) { 
     viewHolder.txt_damount.setTextColor(Color.rgb(8, 138, 8)); 
     viewHolder.txt_damount.setText("Debit $ " + amount); 
    } 

    // Get current date 
    String currentDate = "Next Payment On: " + dateFormat.format(new Date()); 

    // If current date matches with the next payment date, insert new 
    // transaction record 
    if (currentDate.equals(viewHolder.txt_ddate.getText())) { 
     DatabaseAdapter mDbHelper = new DatabaseAdapter(Recurring.this); 
     mDbHelper.createDatabase(); 
     mDbHelper.open(); 
     TransactionRecModel trm = new TransactionRecModel(); 
     CategoryController cc = new CategoryController(mDbHelper.open()); 

     trm.setDate(dateFormat.format(new Date())); 
     if (_recurlist.get(position).getRecurringType().equals("W")) { 
      trm.setType("W"); 
     } else if (_recurlist.get(position).getRecurringType().equals("D")) { 
      trm.setType("D"); 
     } 
     trm.setAmount(Float.parseFloat(formatAmount)); 

     TransactionRecController trc = new TransactionRecController(mDbHelper.open()); 
     if (trc.addTransactionRec(trm)) { 
      // After successfully insert transaction record, update the 
      // recurring start date 
      rm = new RecurringModel(); 
      rm.setRecurringID(recurID); 
      rm.setRecurringStartDate(dateFormat.format(new Date())); 

      RecurringController rc = new RecurringController(mDbHelper.open()); 
      if (rc.updateRecurringDate(rm)) { 
       mDbHelper.close(); 
      } 
     } 
    } 

    return convertView; 
} 

從我試圖讓當前的日期和下一個付款日期根據頻率計算比較的代碼。但是,使用這些代碼,它不會在後臺運行。

比方說,我設置了一個週期性事件,每天都會重複一次。但是我今天沒有運行這個應用程序。正確的說,循環應該在後臺運行並執行循環。但不知何故,事實並非如此。

我不知道是否需要像AlarmManager這樣的服務來做到這一點?

在此先感謝。

編輯

所以我已經改變爲一部分,當我嘗試比較的日期,如果日期匹配,就會調用alarmManager一路上解析某些值:

if (currentDate.equals(viewHolder.txt_ddate.getText())) { 
    long when = new Date().getTime(); 
    notificationCount = notificationCount + 1; 
    AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
    Intent notificationIntent = new Intent(context, ReminderAlarm.class); 
    notificationIntent.putExtra("RecurID", recurID);     
    notificationIntent.putExtra("Date", dateFormat.format(new Date())); 
    notificationIntent.putExtra("Description", viewHolder.txt_ddesc.getText().toString()); 
    notificationIntent.putExtra("Type", _recurlist.get(position).getRecurringType()); 
    notificationIntent.putExtra("Amount", Float.parseFloat(formatAmount)); 
    notificationIntent.putExtra("CategoryID", viewHolder.txt_dcat.getText().toString()); 
    notificationIntent.putExtra("NotifyCount", notificationCount); 
    PendingIntent pi = PendingIntent.getBroadcast(context, notificationCount, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
    mgr.set(AlarmManager.RTC_WAKEUP, when, pi); 
} 

而且在我ReminderAlarm類,我在執行INSERT和UPDATE SQL語句:

public class ReminderAlarm extends BroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent) { 

    String recurID = intent.getStringExtra("RecurID"); 
    String date = intent.getStringExtra("Date"); 
    String description = intent.getStringExtra("Description"); 
    String type = intent.getStringExtra("Type"); 
    Float amount = Float.parseFloat(intent.getStringExtra("Amount")); 
    String categoryID = intent.getStringExtra("CategoryID"); 

    DatabaseAdapter mDbHelper = new DatabaseAdapter(ReminderAlarm.this); 
    mDbHelper.createDatabase(); 
    mDbHelper.open(); 
    TransactionRecModel trm = new TransactionRecModel(); 
    CategoryController cc = new CategoryController(mDbHelper.open()); 

    trm.setDate(date); 
    trm.setTransDescription(description); 
    if (type.equals("W")) { 
     trm.setType("W"); 
    } else if (type.equals("D")) { 
     trm.setType("D"); 
    } 
    trm.setAmount(amount); 

    // Get the categoryID based on categoryName 
    String catID = cc.getCatIDByName(categoryID); 
    trm.setCategory(catID); 

    TransactionRecController trc = new TransactionRecController(mDbHelper.open()); 
    if (trc.addTransactionRec(trm)) { 
     // After successfully insert transaction record, update the 
     // recurring start date 
     RecurringModel rm = new RecurringModel(); 
     rm.setRecurringID(recurID); 
     rm.setRecurringStartDate(date); 

     RecurringController rc = new RecurringController(mDbHelper.open()); 
     if (rc.updateRecurringDate(rm)) { 
      mDbHelper.close(); 
     } 
    } 
} 

}

+0

你絕對不應該在'Adapter'中做所有這些工作。你*應該*在'Loader'中完成,然後將顯示就緒數據傳遞給適配器。你應該閱讀d.android.com上的教程,因爲幾乎你在這裏做的每件事都是錯誤的。 – 2014-09-19 13:41:00

+0

對不起,裝載機是指onCreate的活動方法還是? – 2014-09-19 13:42:27

+0

@PaulBurke你想介紹一下嗎?因爲我不知道如何做到這一點 – 2014-09-19 13:59:26

回答

1

您的Adapter應該接收的數據是準備好顯示。每次當ListView項目出現在屏幕上時,都會調用getView,所以如果希望保持60fps滾動,則希望將您的工作保持在16ms以下。因此,您應該在之前完成所有繁重的工作它到達適配器。

由於數據庫數據通常不是顯示就緒的,因此您通常會使用Loader來獲取數據,並將其轉換爲適用於適配器的「項目」列表。這應發生在您的ActivityFragment中,並且您填入AdapteronLoadFinished。這通常意味着創建一個新的POJO來表示顯示數據。

最好的開始是Loader tutorial

如果您想要設置循環任務,則應該使用AlarmManager,正如您懷疑的那樣。 AlarmManager通常會觸發BroadcastManager,這反過來會產生一個Service來完成這項工作。

按照AlarmManager tutorial瞭解更多詳情。

+0

但是,我應該如何觸發警報,因爲您提供的示例在特定時間段內觸發。但我的情況是基於下一個付款日期和當前日期。 – 2014-09-19 14:03:33

+0

對於你的情況,我想你會在'Loader'中確定這些日期,並在那裏設置警報。 '適配器'應該只關心正在顯示的內容。 – 2014-09-19 14:06:02

+0

加載程序是我從數據庫中獲取所有數據的部分嗎?檢查我的編輯部分 – 2014-09-19 14:09:52