2015-11-11 1 views
4

Я пытаюсь создать программу на Android, которая быстро взаимодействует с удаленным сервисом (~ 40 000/сек), однако все Android IPC, похоже, не в состоянии выполнить эту задачу. Моя первая попытка включала стандартную систему Messenger, которая не смогла сделать больше ~ 2000/секунд, и в равной степени плохая была то, что она, казалось, прерывалась прерывистым отставанием.Rapid IPC с Messenger или AIDL

MainActivity (тест с Messengers)

public class MainActivity extends Activity implements ServiceConnection{ 

    Messenger mServiceMessenger; 
    Messenger mClientMessenger = new Messenger(new ClientHandler()); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Intent intent = new Intent(this,TestService.class); 
     bindService(intent,this, Context.BIND_AUTO_CREATE); 
    } 


    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     mServiceMessenger = new Messenger(service); 
     Message m = Message.obtain(); 
     m.replyTo = mClientMessenger; 
     try { 
      mServiceMessenger.send(m); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) {} 

    public class ClientHandler extends Handler { 
     @Override 
     public void handleMessage(Message msg) { 
      Log.d("Spam","Message Received"); 
     } 
    } 
} 

RemoteService (тест с Messengers)

public class TestService extends Service { 

    private Messenger mServiceMessenger = new Messenger(new ServiceHandler()); 
    private Messenger mClientMessenger; 
    private Random r = new Random(); 

    public TestService() { 
     super(); 
    } 

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


    @Override 
    public IBinder onBind(Intent intent) { 
     return mServiceMessenger.getBinder(); 
    } 

    public void initSpam(){ 
     for(int i=0;i<10;i++) { 
      TimerTask task = new TimerTask() { 
       @Override 
       public void run() { 
        Bundle b = new Bundle(); 
        b.putInt("INT",r.nextInt()); 
        b.putLong("LONG",r.nextLong()); 
        b.putBoolean("BOOL",r.nextBoolean()); 
        b.putFloat("FLOAT",r.nextFloat()); 
        b.putDouble("DOUBLE",r.nextDouble()); 
        b.putString("STRING",String.valueOf(r.nextInt())); 
        Message msg = Message.obtain(); 
        msg.setData(b); 

        try { 
         mClientMessenger.send(msg); 
        } catch (RemoteException e) { 
         e.printStackTrace(); 
        } 
       } 
      }; 
      Timer timer = new Timer(); 
      timer.scheduleAtFixedRate(task,1,1); 
     } 
    } 

    public class ServiceHandler extends Handler { 
     @Override 
     public void handleMessage(Message msg) { 
      mClientMessenger = msg.replyTo; 
      initBarrage(); 

     } 
    } 
} 

Вторая попытка была сделана с AIDL. Хотя это также реализует Binders для IPC, я предположил, что он значительно меньше накладных расходов. Однако AIDL доказал, что он не будет значительно более эффективным, чем Messengers, и он также не решил проблему с заиканием.

MainActivity (тест с AIDL)

public class MainActivity extends Activity implements ServiceConnection{ 

    IRemoteService mService; 
    TextView countTextView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Intent intent = new Intent(this,TestService.class); 
     bindService(intent,this, Context.BIND_AUTO_CREATE); 
    } 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 

     mService = IRemoteService.Stub.asInterface(service); 
     try { 
      mService.registerCallback(mClientBinder); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) {} 


    public final IServiceAidlCallback.Stub mClientBinder = new IServiceAidlCallback.Stub(){ 
     public void basicTypes(int anInt, long aLong, boolean aBoolean, 
           float aFloat, double aDouble, String aString){ 
      Log.d("Spam","Callback Received"); 
     } 
    }; 
} 

RemoteService (тест с AIDL)

public class TestService extends Service { 

    private Random r = new Random(); 

    private IServiceAidlCallback mClientCallback; 

    public TestService() { 
     super(); 
    } 

    @Override 
    public void onRebind(Intent intent) { 
     super.onRebind(intent); 
    } 

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

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     return super.onStartCommand(intent, flags, startId); 
    } 

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

    public final IRemoteService.Stub mBinder = new IRemoteService.Stub(){ 
     public void registerCallback(IBinder callback){ 

      mClientCallback = IServiceAidlCallback.Stub.asInterface(callback); 
      initSpam(); 

     } 
    }; 

    public void initSpam(){ 
     for(int i=0;i<10;i++) { 
      TimerTask task = new TimerTask() { 
       @Override 
       public void run() { 
        try { 
         mClientCallback.basicTypes(
           r.nextInt(), 
           r.nextLong(), 
           r.nextBoolean(), 
           r.nextFloat(), 
           r.nextDouble(), 
           String.valueOf(r.nextInt())); 
        } catch (RemoteException e) { 
         e.printStackTrace(); 
        } 
       } 
      }; 
      Timer timer = new Timer(); 
      timer.scheduleAtFixedRate(task,1,1); 
     } 
    } 
} 

я делаю что-то неправильно в любом из этих случаев, которые препятствовали бы мне получить выше ~ 5000/сек? или есть еще одна система для Android IPC, о которой я не знал?

+1

Вы не собираетесь быть в состоянии сделать что-либо поддерживается на ~ 40000 раз в секунду без заикания, не говоря уже о разных процессах, на готовом оборудовании с поставляемым производителем ROM, f с Android SDK. Приложения SDK не контролируют планирование потоков и процессов. – CommonsWare

+1

вы могли бы считать необработанным протоколом 'Binder' (' transact'/'onTransact'), который должен быть быстрее AIDL, но не так много, также сокеты или' MemoryFile', может быть (я никогда не использовал его на самом деле, поэтому я не уверен, насколько это быстро возможно)? – pskink

+0

@CommonsWare Я могу получить ~ 40 000 через локальную сеть с telnet для моей удаленной службы, которая по своей сути является IPC, нет ничего на Android, которая может соответствовать этому? – Beryllium

ответ

2

сделать что-то подобное:

MainActivity

// use it for writing: stream.write(byte[]) 
// (make sure to write as biggest data chunks as possible) 
// or wrap it around some other streams like DataOutputStream 
private OutputStream stream; 

// ServiceConnection implementation 
@Override 
public void onServiceConnected(ComponentName name, IBinder service) { 
    try { 
     ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); 
     stream = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]); 

     Parcel data = Parcel.obtain(); 
     FileDescriptor readFileDescriptor = pipe[0].getFileDescriptor(); 
     data.writeFileDescriptor(readFileDescriptor); 
     service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    Log.d(TAG, "onServiceConnected " + stream); 
} 

RemoteService

@Override 
public IBinder onBind(Intent intent) { 
    Log.d(TAG, "onBind "); 
    return binder; 
} 

IBinder binder = new Binder() { 
    @Override 
    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { 
     ParcelFileDescriptor pfd = data.readFileDescriptor(); 
     final InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(pfd); 
     // do something with a 'stream', start a new Thread for example and read data in a loop 
     ... 
     ... 
     return true; 
    } 
}; 

 Смежные вопросы

  • Нет связанных вопросов^_^