Android 与网络服务进行通信

Android 与网络服务进行通信,android,ipc,live-wallpaper,Android,Ipc,Live Wallpaper,是否有任何方法可以从活动直接与墙纸服务通信?看起来我不能使用正常的服务通信类,因为我要扩展的墙纸服务类中声明了onBind方法。值得注意的是,我指的是我的壁纸服务,而不是任何 如果这是不可能的,有什么解决办法吗?我的解决方案是使用本地套接字。我在墙纸的引擎的构造函数中创建了LocalServerSocket的实例。下面是一个快速实现。服务器在单独的线程上运行,并直接与MyEngine的生命周期相关联。当continuescocket设置为false时,线程将停止。这种情况发生在onDestroy

是否有任何方法可以从
活动
直接与
墙纸服务
通信?
看起来我不能使用正常的服务通信类,因为我要扩展的墙纸服务类中声明了
onBind
方法。值得注意的是,我指的是我的壁纸服务,而不是任何


如果这是不可能的,有什么解决办法吗?

我的解决方案是使用本地套接字。我在墙纸的
引擎的构造函数中创建了
LocalServerSocket
的实例。下面是一个快速实现。服务器在单独的线程上运行,并直接与MyEngine的生命周期相关联。当
continuescocket
设置为
false
时,线程将停止。这种情况发生在onDestroy上。解决方法是向我们自己的服务器发送一条消息,这样它将再次运行循环并检查
continueSocket
(现在是
false
),关闭服务器。检查
closeSocketServer
方法。我在示例中的
onDestroy
中运行了它,但是您可能希望在其他地方使用它,比如
onsurfacedestromed
,并添加您自己的健全性检查

public class MyWallpaperService extends WallpaperService {
    @Override
    public Engine onCreateEngine() {
        return new MyEngine();
    }

    private class MyEngine extends Engine {

        private boolean continueSocket = true;

        MyEngine() {
            new Thread() {
                @Override
                public void run() {
                    try {
                        LocalServerSocket server = new LocalServerSocket("MyAddress");
                        Log.d("SERVER READY", "Server is ready.");
                        while(continueSocket) {
                            LocalSocket receiver = server.accept();
                            if(receiver != null) {
                                InputStream input = receiver.getInputStream();
                                byte[] data = IOUtils.toByteArray(input);
                                Log.d("GOT DATA", new String(data));
                            }
                        }
                        server.close();
                    } catch (IOException ex) {
                        Log.wtf("IOEXCEPTION", ex);
                    }
                }
            }.start();
        }

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

        private void closeSocketServer() {
            continueSocket = false;
            try {
                LocalSocket socket = new LocalSocket();
                socket.connect(new LocalSocketAddress("MyAddress"));
                socket.getOutputStream().write(new byte[0]);
                socket.getOutputStream().close();
                socket.close();
            } catch (IOException ex) {
                //
            }
        }
    }
}
在我的
活动中
可以这么简单

try {
    LocalSocket sender = new LocalSocket();
    sender.connect(new LocalSocketAddress("MyAddress"));
    String data = "Hello world!";
    Log.d("SENT DATA", data);
    sender.getOutputStream().write(data.getBytes());
    sender.getOutputStream().close();
    sender.close();
} catch (IOException ex) {
    Log.wtf("IOEXCEPTION", ex);
}
Logcat最终看起来像这样:

D/SERVER READY﹕ Server is ready. (when the wallpaper starts up)
D/SENT DATA﹕ Hello world! (when the activity sends data)
D/GOT DATA﹕ Hello world! (when the wallpaper gets the data)

在您的Web服务onCreateEngine中:

IntentFilter intentFilter = new IntentFilter("your.package.your.action");
MyBroadcastReceiver mReceiver = new MyBroadcastReceiver(mRenderer);
LocalBroadcastManager.getInstance(getApplicationContext())
        .registerReceiver(mReceiver, intentFilter);
在伦德勒先生的课堂上:

public void receiveCommand(int i) {
    Log.d("got", String.valueOf(i));
}
接收器类别:

public class MyBroadcastReceiver extends BroadcastReceiver {
    private final MyRenderer _mRenderer;

    public MyBroadcastReceiver(MyRenderer mRenderer) {
        _mRenderer = mRenderer;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        _mRenderer.receiveCommand(intent.getExtra("msg", -1));
    }
}
现在从活动中呼叫:

Intent in = new Intent();
in.setAction("your.package.your.action");
in.setExtra("msg", 42);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(in);

看起来,普通的Linux套接字。显然,这可以通过在套接字上调用
shutdown
来解决(至少在棒棒糖之后的版本上):
android.system.Os.shutdown(socalServerSocket.getFileDescriptor(),0)