2

私はアンドロイドの初心者です。私のアプリでは、多対多のチャットを作成し、サーバーからメッセージのリストを更新する必要があります。これを行うために、私はサーバーから毎秒更新するサービスを作成しました。正しい方法でサービスとそのアプリケーションの間でデータをやりとりする方法は?

私の問題は、データをアプリケーションに渡す方法がわかりません。私はインテントとブロードキャストレシーバーを使用してそれを行うべきであることを知っていますが、私は、アプリケーションに渡すためにシリアル化しなければならないBundleオブジェクトに固執していました。効率的。

今のところ私は自分のアプリケーションのリファレンスを使用しています(それはいいとは思いますが、理由はわかりません)、サービスのサーバーからのすべての更新後にアプリケーション機能を有効にして、 。また、私が思うかもしれない私のコードは、同様に初心者のためのいくつかの良いを行います:)

public class UpdateChatService extends Service { 

private static final long DELAY_FOR_CHAT_TASK = 0; 
private static final long PERIOD_FOR_CHAT_TASK = 1; 
private static final TimeUnit TIME_UNIT_CHAT_TASK = TimeUnit.SECONDS; 

//private Task retryTask; TODO: check this out 
private ScheduledExecutorService scheduler; 

private boolean timerRunning = false; 
private long RETRY_TIME = 200000; 
private long START_TIME = 5000; 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 

    scheduleChatUpdate(); 
} 

private void scheduleChatUpdate() { 
    BiggerGameApp app = (BiggerGameApp) getApplication(); 
    this.scheduler = Executors.newScheduledThreadPool(3); 
    this.scheduler.scheduleAtFixedRate(new UpdateChatTask(app), 
      DELAY_FOR_CHAT_TASK, PERIOD_FOR_CHAT_TASK, 
      TIME_UNIT_CHAT_TASK); 
    timerRunning = true; 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if (!timerRunning) { 
     scheduleChatUpdate(); 
    } 

    return super.onStartCommand(intent, flags, startId); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 

    if (scheduler != null) { 
     scheduler.shutdown(); 
    } 

    timerRunning = false; 
} 

}ここで

は、非同期タスクのコードのサービスで実行されます。 私が間違っていることを教えてください。また、サービスからアプリケーションにデータを渡す方法も教えてください。

public void run() { 
    try { 
     if (this.app.getLastMsgFromServer() == null) { 
      this.app.setLastMsgFromServer(new Message(new Player(DEFAULT_EMAIL), "", -1)); 
      this.app.getLastMsgFromServer().setMessageId(-1); 
     } 

     Gson gson = new GsonBuilder() 
     .registerTypeAdapter(DateTime.class, new DateTimeTypeConverter()) 
     .create(); 
     ServerHandler serverHandler = new ServerHandler(); 

     String jsonString = gson.toJson(this.app.getLastMsgFromServer()); 

     // Sending player to servlet in server 
     String resultString = serverHandler.getResultFromServlet(jsonString, "GetListOfMessages");  

     if (resultString.contains("Error")) { 
      return; 
     } 

     // Parsing answer 
     JSONObject json = new JSONObject(resultString); 
     Status status = null; 
     String statusString = json.getString("status");  

     if (statusString == null || statusString.length() == 0) 
      return; 

     status = Status.valueOf(statusString); 

     if (Status.SUCCESS.equals(status)) {  
      ArrayList<Message> tempChat = null; 

      JSONArray jsonList = json.getJSONArray("data"); 
      MyJsonParser jsonParser = new MyJsonParser(); 
      tempChat = jsonParser.getListOfMessagesFromJson(jsonList.toString());  

      if (tempChat != null && tempChat.size() != 0) { 
       // After getting the chat from the server, it saves the last msg 
       // For next syncing with the server 
       this.app.setLastMsgFromServer(tempChat.get(LAST_MSG_INDEX)); 

       tempChat.addAll(this.app.getChat()); 

       if (tempChat.size() > SIZE_OF_USER_CHAT) { 
        tempChat = (ArrayList<Message>) tempChat.subList(0, SIZE_OF_USER_CHAT - 1); 
       } 

       this.app.setChat(tempChat); 
       this.app.updateViews(null); 
      } 
     } 

     return; 

答えて

0

サービスと残りのアプリケーション(アクティビティ)で共有される静的メモリを使用できます。このサービスを外部のアプリケーションに公開する予定がない場合は、バンドル経由のデータのシリアライズ/デシリアライズよりも静的なメモリを共有するほうがよいでしょう。

外界に露出するコンポーネントには、バンドルベースのアプローチが推奨されます。一般的なアプリでは、通常、アプリマニフェストファイルにプライマリアクティビティだけが表示されます。

0

サービスを有効にしないと、スタティックメモリとコールバック機能で処理できます。 そうでなければ、ブロードキャストを送信できます。

2

サービスはローカルのみです(「はい」と仮定します)。以下に示すようにローカル専用サービスと

通信は、バックandroid.os.Binderのインスタンスを渡すことによって行うことができる。

public class UpdateChatService extends Service { 
    public static final class UpdateChat extends Binder { 
     UpdateChatService mInstance; 
     UpdateChat(UpdateChatService instance) { 
      mInstance = instance; 
     } 

     public static UpdateChat asUpdateChat(IBinder binder) { 
      if (binder instanceof UpdateChat) { 
       return (UpdateChat) binder; 
      } 
      return null; 
     } 

     public String pollMessage() { 
      // Takes a message from the list or returns null 
      // if the list is empty. 
      return mInstance.mMessages.poll(); 
     } 

     public void registerDataSetObserver(DataSetObserver observer) { 
      mInstance.mObservable.registerObserver(observer); 
     } 

     public void unregisterDataSetObserver(DataSetObserver observer) { 
      mInstance.mObservable.unregisterObserver(observer); 
     } 
    } 

    private ScheduledExecutorService mScheduler; 
    private LinkedList<String> mMessages; 
    private DataSetObservable mObservable; 

    @Override 
    public IBinder onBind(Intent intent) { 
     return new UpdateChat(this); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     mObservable = new DataSetObservable(); 
     mMessages = new LinkedList<String>(); 
     mScheduler = Executors.newScheduledThreadPool(3); 
     mScheduler.scheduleAtFixedRate(new UpdateChatTask(), 0, 1, TimeUnit.SECONDS); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     mScheduler.shutdownNow(); 
     mObservable.notifyInvalidated(); 
    } 

    class UpdateChatTask implements Runnable { 
     int mN = 0; 
     public void run() { 
      // This example uses a list to keep all received messages, your requirements may vary. 
      mMessages.add("Message #" + (++mN)); 
      mObservable.notifyChanged(); 
     } 
    } 
} 

この例では、(この場合ListActivityで)Activity等を供給するために使用することができますこの:

public class ChattrActivity extends ListActivity implements ServiceConnection { 
    LinkedList<String> mMessages; 
    ArrayAdapter<String> mAdapter; 
    UpdateChat mUpdateChat; 
    DataSetObserver mObserver; 
    Runnable mNotify; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mMessages = new LinkedList<String>(); 
     mNotify = new Runnable() { 
      public void run() { 
       mAdapter.notifyDataSetChanged(); 
      } 
     }; 
     mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mMessages); 
     getListView().setAdapter(mAdapter); 
     // Bind to the Service if you do not need it to persist when this Activity 
     // dies - otherwise you must call #startService(..) before! 
     bindService(new Intent(this, UpdateChatService.class), this, BIND_AUTO_CREATE); 
    } 

    /** 
    * @see android.app.ListActivity#onDestroy() 
    */ 
    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     if (mUpdateChat != null) { 
      mUpdateChat.unregisterDataSetObserver(mObserver); 
      unbindService(this); 
     } 
    } 

    public void onServiceConnected(ComponentName name, IBinder service) { 
     mUpdateChat = UpdateChat.asUpdateChat(service); 
     mObserver = new DataSetObserver() { 
      @Override 
      public void onChanged() { 
       String message; 
       while ((message = mUpdateChat.pollMessage()) != null) { 
        mMessages.add(message); 
       } 
       runOnUiThread(mNotify); 
      } 
      @Override 
      public void onInvalidated() { 
       // Service was killed - restart or handle this error somehow. 
      } 
     }; 
     // We use a DataSetObserver to notify us when a message has been "received". 
     mUpdateChat.registerDataSetObserver(mObserver); 
    } 

    public void onServiceDisconnected(ComponentName name) { 
     mUpdateChat = null; 
    } 
} 

あなたはAIDLインターフェイスを実装を検討すべきであるプロセス間で通信する必要がある場合 - しかし、「ローカル」のバージョンでこのパターンがうまく動作します&含みませんグローバルApplicationインスタンスを悪用する。

関連する問題