0

私のアプリは GCM からメッセージを受信でき、電話の SQLlite データベースにメッセージを保存します。メッセージは、リストビューを持つアクティビティで表示できます。

以下のコードでは、onPause() 関数が listView を更新します。これは、更新時にアクティビティが表示されない場合にのみ機能するため、適切な実装ではありません。アクティビティが更新時に表示される場合、リストは静的で更新されません。

質問:

  1. アクティビティが表示されているときにリストビューを更新するにはどうすればよいですか? または、アクティビティが表示されるたびに常に最新のデータが表示されるように、バックグラウンド サービスを使用してアダプターを更新する方法はありますか。

  2. この種の機能は現在 Android では不可能であり、「pull-to-refresh」のような別のものを実装する必要がありますか?

OnResume() でリストビューを更新すると、アプリケーションがクラッシュし、null ポインター例外が表示されます。

アクティビティ:

public class NotesView extends Activity implements OnItemClickListener {


    ListView listView;
    NoteAdapter objAdapter;
    NotificationsDatabase db = new NotificationsDatabase(this);
    List<Notes> listAlerts;
    String note;
    String time;
    TextView noteView;
    TextView timeView;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.note);

        listView = (ListView) findViewById(R.id.notelist);
        listView.setOnItemClickListener(this);
        noteView = (TextView) findViewById(R.id.noteDisplay);
        timeView = (TextView) findViewById(R.id.notetimeStampDisplay);
        new MyTask().execute();


    }

    // My AsyncTask start...
    class MyTask extends AsyncTask<Void, Void, List<Notes>> {

        ProgressDialog pDialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            pDialog = new ProgressDialog(NotesView.this);
            pDialog.setMessage("Loading...");
            pDialog.setCancelable(false);
            pDialog.show();

            if (isCancelled()) {

                this.cancel(true);
            }

        }


        @Override
        protected List<Notes> doInBackground(Void... params) {


            db.open();
            listAlerts = db.getData();

            if (isCancelled()) {

                this.cancel(true);
            }


            return null;
        }

        protected void onPostExecute(List<Notes> alerts) {


            if (null != pDialog && pDialog.isShowing()) {
                pDialog.dismiss();
            }
            db.close();
            setAdapterToListview();

        }


    }// end myTask


    public void setAdapterToListview() {

        objAdapter = new NoteAdapter(NotesView.this, R.layout.row_notes, listAlerts);
        objAdapter.sortByNoteDesc();
        objAdapter.notifyDataSetChanged();
        listView.setAdapter(objAdapter);
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            Intent intent = new Intent(
                    NotesView.this.getApplicationContext(),
                    TabBarExample.class);
            intent.putExtra("goToTab", "Alerts");
            startActivity(intent);
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }


    public void onItemClick(AdapterView<?> parent, View viewDel, int position,
                            long id) {


        for (int i = 0; i < 1; i++) {
            Notes item = listAlerts.get(position);
            int ids = item.getId();
            note = item.getNote();
            time = item.getTimeStamp();

        }

        System.out.println(note + "  " + time);

        //      
    }


    @Override
    protected void onResume() {

        super.onResume();


    }

    @Override
    protected void onPause() {
        super.onPause();

        setContentView(R.layout.note);

        listView = (ListView) findViewById(R.id.notelist);
        listView.setAdapter(null);
        listView.setOnItemClickListener(this);
        noteView = (TextView) findViewById(R.id.noteDisplay);
        timeView = (TextView) findViewById(R.id.notetimeStampDisplay);
        new MyTask().execute();


    }

    @Override
    protected void onDestroy() {

    }


}

GCMIntentService のコード スニペット

@Override
protected void onMessage(Context context, Intent intent) {
    Log.i(TAG, "Received message");
    //String message = getString(R.string.gcm_message);

    System.out.println("onMessage: ");


    Bundle extras = intent.getExtras();

    String message = extras.getString("message");
    String event_id_from_server = extras.getString("server_id");
    //    displayMessage(context, message);
    generateNotification(context, message);
    saveMsg(message);

    System.out.println("server id is " + event_id_from_server);

    if (event_id_from_server != null) {

        updateLocalDatabase(event_id_from_server);

    }


}

public void saveMsg(String msg) {

    boolean worked = true;
    try {

        NotificationsDatabase entry = new NotificationsDatabase(GCMIntentService.this);
        entry.open();
        java.util.Date date = new java.util.Date();
        Timestamp x = new Timestamp(date.getTime());

        String timeStamp = x.toLocaleString();
        entry.createEntry(msg, timeStamp);

        entry.close();

        //update adapter service


    } catch (Exception e) {
        worked = false;
        String error = e.toString();
        System.out.println(error);
    } finally {
        if (worked) {


        }

    }
}
4

1 に答える 1

3

コードを少し整理しました。基本的に、すべてのビューの割り当ては onCreate で 1 回行い、データのロードは onResume() で行う必要があります。これが役立つかどうかを確認してください:

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.note);
   listView = (ListView) findViewById(R.id.notelist);
   listView.setAdapter(null);
   listView.setOnItemClickListener(this);
   noteView = (TextView) findViewById(R.id.noteDisplay);
   timeView = (TextView) findViewById(R.id.notetimeStampDisplay);
}

@Override
protected void onResume() {
   super.onResume();
   new MyTask().execute();
}

@Override
   protected void onPause() {
   super.onPause();
}
于 2012-10-17T21:23:48.337 に答える