Hot questions for Using ZeroMQ in android

Question:

I'm trying to program ZeroMQ on my android device and I know how to use ZeroMQ (From C++, Php, .Net , I'm all the time using it.) If I list what I've done until now :

  • From Dependencies in Android Studio, I added org.zeromq:jeromq:0.3.5 from maven central search.
  • After that, I put a code like the following :
try
{
    ZMQ.Context context = ZMQ.context(1);

    //  Socket to talk to server
    System.out.println("Connecting to hello world server...");

    ZMQ.Socket requester = context.socket(ZMQ.REQ);
    requester.connect("tcp://192.168.2.127:5555");

    for (int requestNbr = 0; requestNbr != 10; requestNbr++) {
        String request = "Hello";
        System.out.println("Sending Hello " + requestNbr);
        requester.send(request.getBytes(), 0);

        byte[] reply = requester.recv(0);
        System.out.println("Received " + new String(reply) + " " + requestNbr);
    }
    requester.close();
    context.term();


}
catch (Exception e)
{
   Log.e("Error", "Exception : " + e.getMessage());
}

When I run this, I got an exception like the following :

01-03 02:20:55.200 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.os.PersistableBundle', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.200 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.os.PersistableBundle', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.200 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.media.session.MediaController', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.210 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.widget.Toolbar', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.220 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.app.ActivityManager$TaskDescription', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.230 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.app.SharedElementCallback', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.230 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.os.PersistableBundle', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.240 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.app.SharedElementCallback', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.250 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.app.assist.AssistContent', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.260 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.view.SearchEvent', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:20:55.270 12562-12562/mia.face.id.zeromq E/dalvikvm: Could not find class 'android.os.PersistableBundle', referenced from method mia.face.id.zeromq.MainActivity.access$super
01-03 02:21:08.080 12562-12562/mia.face.id.zeromq E/Error: Exception : null

I'm actually not new in programming but in Android/Java stuffs. I cannot figure it out how to solve this problem. I searched on the internet however couldnt find something.

If you can help me, I'll be very pleased.

Thanks in advance.

(Addtion, I forget to include this one : )
01-03 03:12:58.430 1374-1374/mia.face.id.zmqtestest E/Error: Exception
                                                         android.os.NetworkOnMainThreadException
                                                             at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
                                                             at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:168)
                                                             at libcore.io.IoBridge.sendto(IoBridge.java:490)
                                                             at java.nio.SocketChannelImpl.writeImpl(SocketChannelImpl.java:391)
                                                             at java.nio.SocketChannelImpl.write(SocketChannelImpl.java:349)
                                                             at java.nio.PipeImpl$PipeSinkChannel.write(PipeImpl.java:114)
                                                             at zmq.Signaler.send(Signaler.java:121)
                                                             at zmq.Mailbox.send(Mailbox.java:85)
                                                             at zmq.Ctx.sendCommand(Ctx.java:388)
                                                             at zmq.ZObject.sendCommand(ZObject.java:362)
                                                             at zmq.ZObject.sendPlug(ZObject.java:171)
                                                             at zmq.ZObject.sendPlug(ZObject.java:161)
                                                             at zmq.Own.launchChild(Own.java:126)
                                                             at zmq.SocketBase.addEndpoint(SocketBase.java:550)
                                                             at zmq.SocketBase.connect(SocketBase.java:542)
                                                             at org.zeromq.ZMQ$Socket.connect(ZMQ.java:1246)
                                                             at mia.face.id.zmqtestest.MainActivity$1.onClick(MainActivity.java:34)
                                                             at android.view.View.performClick(View.java:4438)
                                                             at android.view.View$PerformClick.run(View.java:18422)
                                                             at android.os.Handler.handleCallback(Handler.java:733)
                                                             at android.os.Handler.dispatchMessage(Handler.java:95)
                                                             at android.os.Looper.loop(Looper.java:136)
                                                             at android.app.ActivityThread.main(ActivityThread.java:5017)
                                                             at java.lang.reflect.Method.invokeNative(Native Method)
                                                             at java.lang.reflect.Method.invoke(Method.java:515)
                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:813)
                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
                                                             at dalvik.system.NativeStart.main(Native Method)

Answer:

Android HttpGet android.os.NetworkOnMainThreadException

From here, I found the answer, actually the methodology which is about network operation should be in background task.

Maybe this will help for others to shorten the time they are spending for research.

Regards.

Question:

In my client I receive via ZeroMQ a lot of input, which needs to be constantly updated. My server is written in python, but that should not matter. So this is what I do in my MainActivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /********************************NETWORK********************************/
        new NetworkCall().execute("");
    }

    private class NetworkCall extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            while (true) {
                try {
                    ZMQ.Context context = ZMQ.context(1);

                    // Connect to server
                    ZMQ.Socket requester = context.socket(ZMQ.REQ);
                    String address = "tcp://xxx.xx.xx.xx";
                    int port = 5000;
                    requester.connect(address + ":" + port);

                    // Initialize poll set
                    ZMQ.Poller poller = new ZMQ.Poller(1);
                    poller.register(requester, ZMQ.Poller.POLLIN);

                    requester.send("COORDINATES");

                    //while (true) {
                    String data;
                    poller.poll();

                    data = requester.recvStr();
                    System.out.println(data);

                    if (data == null) {
                        try {
                            sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } requester.close();
                } catch (IllegalStateException ise) {
                    ise.printStackTrace();
                }
            }
        }

        @Override
        protected void onPostExecute(String result) {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }
}

After executing this code on my device, I'll get like 5-9 input data strings, which I receive from the server, but then the following exception appears:

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
                  Process: com.example.viktoria.gazefocus, PID: 31339
                  java.lang.RuntimeException: An error occurred while executing doInBackground()
                      at android.os.AsyncTask$3.done(AsyncTask.java:353)
                      at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
                      at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:271)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
                      at java.lang.Thread.run(Thread.java:764)
                   Caused by: com.example.viktoria.gazefocus.zmq.ZError$IOException: java.io.IOException: Too many open files
                      at com.example.viktoria.gazefocus.zmq.Signaler.makeFdPair(Signaler.java:94)
                      at com.example.viktoria.gazefocus.zmq.Signaler.<init>(Signaler.java:50)
                      at com.example.viktoria.gazefocus.zmq.Mailbox.<init>(Mailbox.java:51)
                      at com.example.viktoria.gazefocus.zmq.Ctx.<init>(Ctx.java:128)
                      at com.example.viktoria.gazefocus.zmq.ZMQ.zmq_ctx_new(ZMQ.java:244)
                      at com.example.viktoria.gazefocus.zmq.ZMQ.zmqInit(ZMQ.java:277)
                      at org.zeromq.ZMQ$Context.<init>(ZMQ.java:269)
                      at org.zeromq.ZMQ.context(ZMQ.java:254)
                      at com.example.viktoria.gazefocus.MainActivity$NetworkCall.doInBackground(MainActivity.java:73)
                      at com.example.viktoria.gazefocus.MainActivity$NetworkCall.doInBackground(MainActivity.java:67)
                      at android.os.AsyncTask$2.call(AsyncTask.java:333)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) 
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) 
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) 
                      at java.lang.Thread.run(Thread.java:764) 
                   Caused by: java.io.IOException: Too many open files
                      at sun.nio.ch.IOUtil.makePipe(Native Method)
                      at sun.nio.ch.PipeImpl.<init>(PipeImpl.java:42)
                      at sun.nio.ch.SelectorProviderImpl.openPipe(SelectorProviderImpl.java:50)
                      at java.nio.channels.Pipe.open(Pipe.java:155)
                      at com.example.viktoria.gazefocus.zmq.Signaler.makeFdPair(Signaler.java:91)
                      at com.example.viktoria.gazefocus.zmq.Signaler.<init>(Signaler.java:50) 
                      at com.example.viktoria.gazefocus.zmq.Mailbox.<init>(Mailbox.java:51) 
                      at com.example.viktoria.gazefocus.zmq.Ctx.<init>(Ctx.java:128) 
                      at com.example.viktoria.gazefocus.zmq.ZMQ.zmq_ctx_new(ZMQ.java:244) 
                      at com.example.viktoria.gazefocus.zmq.ZMQ.zmqInit(ZMQ.java:277) 
                      at org.zeromq.ZMQ$Context.<init>(ZMQ.java:269) 
                      at org.zeromq.ZMQ.context(ZMQ.java:254) 
                      at com.example.viktoria.gazefocus.MainActivity$NetworkCall.doInBackground(MainActivity.java:73) 
                      at com.example.viktoria.gazefocus.MainActivity$NetworkCall.doInBackground(MainActivity.java:67) 
                      at android.os.AsyncTask$2.call(AsyncTask.java:333) 
                      at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) 
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) 
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) 
                      at java.lang.Thread.run(Thread.java:764) 

Apparently too many files are open. After research (I'm using Ubuntu 16.04) I changed the ulimit with ulimit -n 10000. Still this exception will happen. Sometimes I get more input data, sometimes less. Also if I set something like Executor executor = Executors.newFixedThreadPool(5); into the onCreate() method, nothing will change.

How to overcome this issue?

Thanks for reading!


Answer:

You have a leak because you're not closing / ending / freeing something. I think that the context has to be terminated: context.term() after you close the requester...

Question:

I am using ZeroMQ in android for connecting two devices and I am getting an exception, which is org.zeromq.ZMQException: Errno 48 : Address already in use

Here is my code:

ZMQ.Socket socket = context.socket(             ZMQ.REP );
                            socket.setLinger(   0 );
                            socket.setSndHWM(   0 );
                            socket.setIPv4Only( false );
                            socket.bind(       "tcp://myIP:port" );

while( !Thread.currentThread().isInterrupted() ) {
        byte[] msg = socket.recv( 0 );
        uiThreadHandler.sendMessage( Util.bundledMessage( uiThreadHandler,
                                                          new String( msg )
                                                          )
                                     );
        socket.send( new String( Util.reverseInPlace( msg ) ),
                     0
                     );
}
socket.close();
context.term();
}



ZMQ.Context context = ZMQ.context( 1 );
ZMQ.Socket   socket =     context.socket(          ZMQ.SUB );
                                  socket.connect( "tcp://myIP:port" );
                                  socket.send(     params[0].getBytes(),
                                                   0
                                                   );
String result = new String(       socket.recv( 0 ) );
                                  socket.close();
context.term();
return result;

Answer:

this is a common state in ZeroMQ. .bind() asks, but O/S can & does reject ...

Operating system simply rejected to allow the .bind() method to touch such an <address>:<port#>, that the O/S-resource-manager still believed that is not free and available for any re-use at the moment of call.


For this very reason, ZeroMQ documentation advices, that:

Error handling The binding should use standard error mechanism of the language, whether it is error codes, exceptions etc.

So the proper Exception-handling is always left to the user-code. This is designer's role and responsibility to define, what steps and measures are in place for such a case to remedy the overall strategy of what shall happen next.

During prototyping, it is common to fall into a deadlocked or not yet released address:port, so sometimes just a use of external reset, reboot can provide the missing step to make the toys act accordingly, as expected.

+1 for designing your code with preventive measures ... ZMQ_LINGER being a typical such case. Do this always, automatically. It can just save you hours in debugging.

So, stay tuned and enjoy the powers of distributed-computing with ZeroMQ.

Question:

I tried to use 0.4.2 of jeromq in my android app and added compile 'org.zeromq:jeromq:0.4.2' to build.gradle, but a .connect( String addr ) in ZMQ will crash, no matter if the server program is available.

So I tried to use 0.4.0 of jeromq and .connect() can work, but the .term() of Jeromq will never return when the server program is not available.

Please see a simple version of the code below in Android and the following codes run in a thread of a Intent service.

        ZMQ.Context context = ZMQ.context(1);
        ZMQ.Socket client = context.socket(ZMQ.REQ);                       
        client.connect("tcp://192.168.31.10:13587");           
        client.send("Android");

        final int REQUEST_TIMEOUT = 3000;
        ZMQ.Poller items = context.poller(1);
        items.register(client, ZMQ.Poller.POLLIN);
        items.poll(REQUEST_TIMEOUT);          
        if (items.pollin(0)) {
           String reply = client.recvStr();
        } 

        client.close();
        context.term();

A call to a client.connect( "tcp://192.168.31.10:13587" ) method will crash, if I used 0.4.2 of jeromq. If I used version 0.4.0 or 0.3.6, context.term() never returns, when the server program did not run.


Answer:

You are a happy man, Bob!

The why is simple - the .term()-blocking is an intended behaviour on sockets, that have a LINGER == -1.

just always ( yes, ALWAYS ) setup:

<aSocketInstance>.setsockopt( ZMQ.LINGER, 0 );

for each socket instance, right upon its instantiation, and you are done.

( there are many other API-details to fine tune, if you need to setup your app to become more robust against an error or a mis-use from an uncontrollable set of principally distributed agents, so due care is to be taken )

Question:

I'm new to programming with Message Queues in general and I've been trying to work on a simple Android Application that uses ZeroMQ. I'm running both server and client program on the same device in separate Threads. This is my Server class:

public class ZeroMQServer implements Runnable{
private Handler uiThreadHandler;

public ZeroMQServer(Handler uiThreadHandler) {
    this.uiThreadHandler = uiThreadHandler;
}

@Override
public void run() {
    ZMQ.Context context = ZMQ.context(1);
    ZMQ.Socket socket = context.socket(ZMQ.REP);
    socket.bind("tcp://*:5570");

    while(!Thread.currentThread().isInterrupted()) {
        byte[] msg = socket.recv(0);
        uiThreadHandler.sendMessage(
                Util.bundledMessage(uiThreadHandler, new String(msg)));
        socket.send(Util.reverseInPlace(msg)+"", 0);
    }
    socket.close();
    context.term();
}

And this is the client class:

public class ZeroMQMessageTask extends AsyncTask<String, Void, String> {
private final Handler uiThreadHandler;

public ZeroMQMessageTask(Handler uiThreadHandler){
    this.uiThreadHandler = uiThreadHandler;
}

@Override
protected String doInBackground(String... params) {
    ZMQ.Context context = ZMQ.context(1);
    ZMQ.Socket socket = context.socket(ZMQ.REQ);
    socket.connect("tcp://localhost:5570");

    socket.send(params[0].getBytes(), 0);
    String result = new String(socket.recv(0));

    socket.close();
    context.term();

    return result;
}

@Override
protected void onPostExecute(String result) {
    uiThreadHandler.sendMessage(Util.bundledMessage(uiThreadHandler, result));
}

And this is the snippet of the main activity that starts the server in another Thread and implements a clickListener to call the client.

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

    textView = (TextView)findViewById(R.id.text_console);
    editText = (EditText)findViewById(R.id.text_message);

    new Thread(new ZeroMQServer(serverMessageHandler)).run();

    findViewById(R.id.button_send_message).setOnClickListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    new ZeroMQMessageTask(clientMessageHandler).execute(getTaskInput());
                }

                protected String getTaskInput() {
                    return editText.getText().toString();
                }
            });
}

The problem I'm having is that as soon as the application starts it closes automatically. When I remove the socket.bind("tcp://*:5570"); line from the server, it doesn't close anymore, but also doesn't work the way it's supposed to, as the server won't listen.

I have both INTERNET and ACCESS_WIFI_STATE permissions granted in the manifest.

Any help in this matter is appreciated.

EDIT: I've put a breakpoint at the .bind() line, and this is the error I get:

Didn't find class "java.net.StandardProtocolFamily" on path:
  DexPathList[
    [zip file "/data/app/com.example.victor.zeromqrabbitmq-1/base.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_dependencies_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_0_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_1_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_2_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_3_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_4_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_5_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_6_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_7_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_8_apk.apk",
     zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_9_apk.apk"
     ],
  nativeLibraryDirectories=[
     /data/app/com.example.victor.zeromqrabbitmq-1/lib/arm,
     /vendor/lib, /system/lib
     ]
  ]

EDIT2: Full logcat error:

09-01 00:44:19.878 13082-13205/com.example.victor.zeromqrabbitmq E/Error: Exception: 
09-01 00:44:20.188 13082-13205/com.example.victor.zeromqrabbitmq E/AndroidRuntime: FATAL EXCEPTION:
      AsyncTask #1
        Process: com.example.victor.zeromqrabbitmq, PID: 13082
        java.lang.RuntimeException: An error occurred while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:309)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)
         Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Ljava/net/StandardProtocolFamily;
            at zmq.io.net.tcp.TcpAddress.family(TcpAddress.java:50)
            at zmq.io.net.tcp.TcpListener.setAddress(TcpListener.java:171)
            at zmq.SocketBase.bind(SocketBase.java:363)
            at org.zeromq.ZMQ$Socket.bind(ZMQ.java:2333)
            at com.example.victor.zeromqrabbitmq.ZeroMQServer.doInBackground(ZeroMQServer.java:24)
            at com.example.victor.zeromqrabbitmq.ZeroMQServer.doInBackground(ZeroMQServer.java:10)
            at android.os.AsyncTask$2.call(AsyncTask.java:295)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
            at java.lang.Thread.run(Thread.java:818) 
         Caused by: java.lang.ClassNotFoundException: Didn't find class "java.net.StandardProtocolFamily" on path: DexPathList[[zip file "/data/app/com.example.victor.zeromqrabbitmq-1/base.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.example.victor.zeromqrabbitmq-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.example.victor.zeromqrabbitmq-1/lib/arm, /vendor/lib, /system/lib]]
            at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
            at zmq.io.net.tcp.TcpAddress.family(TcpAddress.java:50) 
            at zmq.io.net.tcp.TcpListener.setAddress(TcpListener.java:171) 
            at zmq.SocketBase.bind(SocketBase.java:363) 
            at org.zeromq.ZMQ$Socket.bind(ZMQ.java:2333) 
            at com.example.victor.zeromqrabbitmq.ZeroMQServer.doInBackground(ZeroMQServer.java:24) 
            at com.example.victor.zeromqrabbitmq.ZeroMQServer.doInBackground(ZeroMQServer.java:10) 
            at android.os.AsyncTask$2.call(AsyncTask.java:295) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
            at java.lang.Thread.run(Thread.java:818) 
            Suppressed: java.lang.ClassNotFoundException: java.net.StandardProtocolFamily
            at java.lang.Class.classForName(Native Method)
            at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
            at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
                    ... 13 more
         Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
09-01 00:44:20.699 13082-13206/com.example.victor.zeromqrabbitmq E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb810d418

Looks like a simple classNotFound error, but it refers to a class that comes with "android package", meaning it doesn't belong to any external libs. So how could it not be found?


Answer:

The problem you are running into is the version of JeroMQ you are using isn't compatible with Android. This pull request: https://github.com/zeromq/jeromq/pull/471 added support for Android 10 and above but it only available on 0.4.3-SNAPSHOT.

Question:

I have a Kivy/python app that communicates with other devices on my home network using zmq. When I try to port to android I get the following message in logcat:

 ImportError: No module named zmq

I guess this means that zmq needs to be implemented o the android device.

I am a complete newbie when it comes to this. There are resources that seem to point in the right direction, but this is all very low level and I'm not even sure it is what I need to do.

Can anyone point to a high level resource that might help me get my head around this?

Thanks


Answer:

Solved by dumping zmq and coding in sockets (see brilliant tutorial here)

Remember to add

android.permissions = INTERNET
android.permission.ACCESS_NETWORK_STATE

to buildozer.spec

Question:

I am writing an Android application that receives a continuous stream of data. I've set up the connection inside a runnable like so:

Runnable runnable = new Runnable()
    {
        public void run()
        {
        ZMQ.Context context = ZMQ.context(1);
        ZMQ.Socket subscriber = context.socket(ZMQ.SUB);
        subscriber.connect("tcp://[IP]:[Port]");
            TextView strDisplay = (TextView) findViewById(R.id.stringDisplay);
            while (!Thread.currentThread ().isInterrupted ())
            {
                // Read message contents
                Log.i("Output", "the while loop ran up to here");
                //*HANGS ON THE LINE BELOW*
                String testcase = subscriber.recvStr(0);
                strDisplay.setText(testcase);
                Log.i("Output", "The while loop completed");
            }

Now, after much scouring of the interwebs, I've come to two conclusions:

1) that recvStr() is a blocking call that waits until it receives something. So that means it hasn't connected properly or something else

and

2) that I may have to set up a filter of some sort?

I can't figure out what I should do next. Any help from someone experienced with JeroMQ or Android server access is greatly appreciated


Answer:

Possibly, you need to subscribe on topic you want to get from publisher or to subscribe on all topics after you made connection.

For example subscribing on single topic:

subscriber.subscribe("topic_to_get".getBytes());

Subscribing on every topic:

subscriber.subscribe("".getBytes());