Özel bir liste bağdaştırıcısı olan bir ListActivity yazdım. OnCreate çalıştırıldığında liste bir ContentProvider'dan güncellenmektedir. Uygulamayı çalıştırdığımda başladığım ve önce ContentProvider'ı güncellediği, ardından da içeriğin güncellendiği bir Yayın gönderen bir hizmetim var.
My ListActivity yayını alır ve ListView'imi güncellemeyi dener. Benim sorunum, ListView bildirilmeksizin ListView adaptör verileri değiştirerek aralıklı hataları alıyorum. Güncellemeden hemen sonra liste bağdaştırıcımdaki notifyDataSetChanged()
yöntemini arıyorum. Neye benziyorsa, liste, hizmetin güncellenmesi için yayını aldığında onCreate'da ilk aramayı yaptıktan sonra güncellenme aşamasındadır, bu yüzden ListView'imi ilk çalıştırmadan güncellemeyi bitirmeden güncellemeye çalışır. Bu mantıklı mı? İşte bazı kodlarım.ListView adaptör veri değişikliği bildirilmeksizin ListView olmaksızın
NOT: Hizmet düzgün çalışıyor, yeni veriler alıyor ve ContentProvider cihazımı güncelleştiriyor ve güncellendiğinde etkinliğimde yayın alıyorum.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
getPrefs();
setContentView(R.layout.main);
// Setup preference listener
preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferences.registerOnSharedPreferenceChangeListener(listener);
// Setup report list adapter
ListView nzbLv = (ListView) findViewById(R.id.report_list);
nzbla = new NZBReportListAdaptor(ctx);
getReports();
nzbla.setListItems(report_list);
nzbLv.setAdapter(nzbla);
// Broadcast receiver to get notification from NZBService to update ReportList
registerReceiver(receiver,
new IntentFilter(NZBService.BROADCAST_ACTION));
startService(new Intent(ctx, NZBService.class));
}
@Override
public void onResume() {
super.onResume();
timerHandler.resume();
new updateSabQueue().execute();
//updateList();
}
@Override
public void onPause() {
super.onPause();
timerHandler.pause();
unregisterReceiver(receiver);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Toast.makeText(ctx, "NZBService broadcast recieved", Toast.LENGTH_SHORT).show();
updateReportList();
}
};
private void updateReportList() {
new updateReportList().execute();
}
private class updateReportList extends AsyncTask<Void, Void, Boolean> {
/* (non-Javadoc)
* @see android.os.AsyncTask#onPreExecute()
* Show progress dialog
*/
protected void onPreExecute() {
}
/* (non-Javadoc)
* @see android.os.AsyncTask#doInBackground(Params[])
* Get new articles from the internet
*/
protected Boolean doInBackground(Void...unused) {
getReports();
return true;
}
/**
* On post execute.
* Close the progress dialog
*/
@Override
protected void onPostExecute(Boolean updated) {
if (updated) {
Log.d(TAG, "NZB report list adapter updated");
synchronized(this) {
nzbla.setListItems(report_list);
}
Log.d(TAG, "NZB report list notified of change");
nzbla.notifyDataSetChanged();
}
}
}
Şimdi bu soruya cevap olduğunu, bunu rastlamak olabilir başkalarına yardım etmek amacıyla zaman güncellenmiş kodu yayınlayacağız.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
getPrefs();
setContentView(R.layout.main);
// Setup preference listener
preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferences.registerOnSharedPreferenceChangeListener(listener);
// Setup report list adapter
ListView nzbLv = (ListView) findViewById(R.id.report_list);
nzbla = new NZBReportListAdaptor(ctx);
report_list.addAll(getReports());
nzbla.setListItems(report_list);
nzbLv.setAdapter(nzbla);
// Broadcast receiver to get notification from NZBService to update ReportList
registerReceiver(receiver,
new IntentFilter(NZBService.BROADCAST_ACTION));
startService(new Intent(ctx, NZBService.class));
}
private class updateReportList extends AsyncTask<Void, Void, ArrayList<Report>> {
/* (non-Javadoc)
* @see android.os.AsyncTask#onPreExecute()
* Show progress dialog
*/
protected void onPreExecute() {
}
/* (non-Javadoc)
* @see android.os.AsyncTask#doInBackground(Params[])
* Get new articles from the internet
*/
protected ArrayList<Report> doInBackground(Void...unused) {
return getReports();
}
/**
* On post execute.
* Close the progress dialog
*/
@Override
protected void onPostExecute(ArrayList<Report> updated) {
nzbla.setListItems(updated);
nzbla.notifyDataSetChanged();
}
}
private ArrayList<Report> getReports() {
ArrayList<Report> reports = new ArrayList<Report>();
ContentResolver r = getContentResolver();
Cursor c = r.query(NZBReportProvider.CONTENT_URI, null, null, null, NZBReportProvider.ARTICLE_KEY_ROWID + " DESC");
startManagingCursor(c);
Log.d(TAG, "NZBReport cursor.getCount=" + c.getCount());
int title = c.getColumnIndex(NZBReportProvider.ARTICLE_KEY_TITLE);
int desc = c.getColumnIndex(NZBReportProvider.ARTICLE_KEY_DESCRIPTION);
int cat = c.getColumnIndex(NZBReportProvider.ARTICLE_KEY_CAT);
int size = c.getColumnIndex(NZBReportProvider.ARTICLE_KEY_SIZE);
int link = c.getColumnIndex(NZBReportProvider.ARTICLE_KEY_LINK);
int catid = c.getColumnIndex(NZBReportProvider.ARTICLE_KEY_CATID);
int date = c.getColumnIndex(NZBReportProvider.ARTICLE_KEY_DATE_ADDED);
int group = c.getColumnIndex(NZBReportProvider.ARTICLE_KEY_GROUP);
if (c.getCount() > 0) {
c.moveToFirst();
do {
URL url = null;
try {
url = new URL(c.getString(link));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
reports.add(new Report(c.getString(title), url, c.getString(desc), c.getString(cat), c.getString(date), c.getString(size), c.getInt(catid), c.getString(group)));
} while (c.moveToNext());
}
return reports;
}
Bu tam olarak sorun. Liste bağdaştırıcım, "report_list" nesnesinin bir ArrayList'i tarafından destekleniyor ve bunu, doğrudan bir iş parçacığı üzerinde yürütülen getReports yöntemimde değiştiriyorum.Yerel bir ArrayList üzerinde çalışmak ve onu iade (ve onPostExecute yöntemime iletmek) için getReports yöntemimi değiştirdim. UI iş parçacığı dışındaki liste bağdaştırıcı verilerimde çalışamayacağımı bilmeme rağmen, beni başarısızlığa uğrayana kadar% 100 tutmuyordum ve düzgün bir şekilde anlamaya zorluyordum (veya daha doğru bir şekilde soruyorum) yardım için burada!) Teşekkür ederim Qberticus! – brockoli