【问题标题】:Schedule TextView update安排 TextView 更新
【发布时间】:2013-11-01 12:02:00
【问题描述】:

在我的应用程序顶部的每个活动中,我都有一个带有TextView 的片段,显示正在发生的当前事件。它看起来像这样:

--------------------
|    Event name    |
|------------------|
|                  |
|                  |
|                  |
|     Activity     |
|     content      |
|                  |
|                  |
|                  |
|                  |
|                  |
--------------------

我想在下一个活动开始时更新活动名称。 我正在使用单例模式,在我的应用程序中,我有 currentEvent 字符串,我在每次活动开始时都会显示该字符串。我将事件保存在数据库中,每个事件都有开始时间。 更新事件名称的最佳方法是什么。如何安排将根据下一个事件的开始时间更新文本视图的事件?

【问题讨论】:

    标签: android scheduled-tasks android-event


    【解决方案1】:

    我认为这样的事情应该可行。 AsyncTask 从数据库中获取当前事件名称和下一个事件开始时间。当它找到这些时,设置当前事件名称,并发布一个可运行对象,并在下一个事件开始时执行。此时,您再次获得该事件名称并设置它,并发布一个新的延迟运行。这样,当前事件名称在创建片段时设置,或者在用户打开片段时设置。

    请注意,您不想为此使用 AlarmManager。来自documentation

    警报管理器适用于您希望拥有 应用程序代码在特定时间运行,即使您的应用程序是 当前未运行。对于正常的计时操作(滴答声、超时、 等)使用Handler 更容易、更高效。

    另外请注意,我没有彻底测试此代码,因此当 Activity 被杀死等时可能会出现一些问题。但这个示例似乎有效,因为它每 10 秒显示一条 Toast 消息。

    public class MyFragment extends Fragment implements Runnable {
    
        TextView currentEventTextView;
        Handler handler;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            handler = new Handler();
        }
    
        @Override
        public void onStart() {
            super.onStart();
            new GetEventTask().execute();
        }
    
        @Override
        public void onStop() {
            handler.removeCallbacks(this);
            super.onStop();
        }
    
        @Override
        public void run() {
            // next event is starting, so obtain it
            new GetEventTask().execute();
        }
    
        private class GetEventTask extends AsyncTask<Void, Void, Event>{
            @Override
            protected Event doInBackground(Void... params) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                // TODO get current name and next start time from db
                Event event = new Event();
                event.name = "Google I/O " + System.currentTimeMillis();
                event.nextStartTime = System.currentTimeMillis() + 10000;
    
                return event;
            }
    
            @Override
            protected void onPostExecute(Event event) {
                currentEventTextView.setText(event.name);
                handler.postDelayed(MyFragment.this, event.nextStartTime - System.currentTimeMillis());
            }
        }
    
    
        private class Event {
            public String name;
            public long nextStartTime;
        }
    }
    

    【讨论】:

    • 我喜欢这个主意。听起来不错:) 我的第一个想法是使用AlarmManager 并在下一个事件开始时间安排警报。这个警报会发送广播,我的片段中会有广播接收器。在onReceive() 方法中的这个广播接收器中,我将更新文本视图以显示新的事件名称。如果应用程序未运行,则不会接收到广播,也不会发生任何事情。你能告诉我你对这个想法有什么看法吗?谢谢
    • 不,您不应该使用 AlarmManager。文档特别解释了 Handler 方法效率更高,正如我在原始答案中所写的那样。
    • 好的,非常感谢,我明天试试看效果如何
    【解决方案2】:

    我按照@Jeffrey 所说的那样做了,但做了一些改动:

    • Application 类中,在onCreate() 中,我获取当前和下一个事件并创建处理程序,就像@Jeffrey 所说的那样,但是在处理程序的Runnablerun() 中,我发送了一个广播。

    • 我在每个 CurrentEvent 片段中注册了一个具有相同 IntentFilterBroadcastReceiver。在接收器的onReceive() 方法中,我更新了TextView

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多