Bug Version 2.0 or SdkVersion greater than 8

wes58

Active Member
Licensed User
Longtime User
I wanted to start using new Visual Designer (Android 4.0 style) with version 2.0 of Basic4Android and I have encountered problems with recompiling previous applications.

The error I got was in simple HTTP response sub.
B4X:
Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
    Dim result As String
    result = Response.GetString("UTF8")
    'Work with the result
End Sub
An Error "android.os.NetworkOnMainThreadException" occurs on line - result = Response.GetString("UTF8").

After trying to find out what could be the problem, I have tried changing minSdkVersion number and I noticed that if it is set in Manifest to anything higher than 8 it comes out with this error.

How can I resolve this problem?

I have also tried to recompile another application and I get errors when trying to compile with SdkVersion 14.
This time, it is when I define type:
B4X:
Type COMPLEX (r As Double, _
      x As Double, _
      z As Double, _
      a As Double)
Dim a As COMPLEX

It is defined with the same name in Sub Globals in two different modules.
With minSdkVersion 14 (maybe from 10 up - I haven't checked it yet) it won't compile unless I use different names for type definition in each module.
It worked fine previously.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. When you add targetSdkVersion attribute with SDK level 14(?) or above then Android do not allow you to do any network calls on the main thread.
You should either use Response.GetAsynchronously or use HttpUtls.

If you are using HttpUtils then you should comment line 100 (under Sub hc_ResponseError):
B4X:
Log(Response.GetString("UTF8"))
This line logs the error message returned from the server. It again reads it on the main thread. After commenting this line all the networking calls will be done on background threads.

2. Types are global to all modules. You do not need (and since v2.00 cannot) define them more than once.
 
Upvote 0

wes58

Active Member
Licensed User
Longtime User
Thanks Erel, That was easy.
Maybe it would be worth while to update help with this information.

2. Types are global to all modules. You do not need (and since v2.00 cannot) define them more than once.

Does it mean that commented lines that are appear when you start the new project are not correct?
B4X:
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
End Sub

So what is the difference now between Process_Globals and Globals?
 
Upvote 0

wes58

Active Member
Licensed User
Longtime User
Declaring a type is different than declaring a variable. Declaring a type is more similar to writing a class module.

You should read the activities life cycle tutorial to better understand the difference between Process_Globals and Globals.

Thanks Erel. I understand the difference between Process_Globals and Globals, I just didn't know about the declaration of type.
 
Upvote 0

wes58

Active Member
Licensed User
Longtime User
1. When you add targetSdkVersion attribute with SDK level 14(?) or above then Android do not allow you to do any network calls on the main thread.
You should either use Response.GetAsynchronously or use HttpUtls.
Now I wanted to use UDP socket to connect to my microcontroller server but it looks like this is not going to work, because of the same reason that "network calls are not allowed on the main thread.
Is there any solution for using UDP sockets?
 
Upvote 0

wes58

Active Member
Licensed User
Longtime User
Can you post the full error message from the logs? And also post the related code.

The errror message is
B4X:
UDPSocket1.Send(Packet)
android.os.NetworkOnMainThreadException
   at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
   at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:175)
   at libcore.io.IoBridge.sendto(IoBridge.java:463)
   at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182)
   at java.net.DatagramSocket.send(DatagramSocket.java:287)
   at anywheresoftware.b4a.objects.SocketWrapper$UDPSocket.Send(SocketWrapper.java:343)
   at com.x10.Home.main._update(main.java:4010)
   at com.x10.Home.main._activityrefresh_click(main.java:836)
   at com.x10.Home.main._activity_resume(main.java:748)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:154)
   at com.x10.Home.main.afterFirstLayout(main.java:90)
   at com.x10.Home.main.access$100(main.java:16)
   at com.x10.Home.main$WaitForLayout.run(main.java:72)
   at android.os.Handler.handleCallback(Handler.java:605)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:4514)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
   at dalvik.system.NativeStart.main(Native Method)
android.os.NetworkOnMainThreadException

Part of the code:
B4X:
If UDPSocket1.IsInitialized = False Then
    UDPSocket1.Initialize("UDP", 0, 50)
End If
    Packet.Initialize(data, code.pr.Host, 30300)
    UDPSocket1.Send(Packet)

Everything has been working fine for a long time with the sdk version 4

Searching the web I found the following information:
StrictMode is enabled in HoneyComb, disable it to avoid NetworkOnMainThreadException
B4X:
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
How to implement it in Basic4Android?
If I was doing a lot of data transfer I may agree with not using network in Main Thread, but the data I receive in UDP mode is around 50 bytes.
 
Last edited:
Upvote 0

wes58

Active Member
Licensed User
Longtime User

Unfortunately it didn't work for me.
Error is:
B4X:
Packet.Initialize(data, code.pr.Host, 30300)

android.os.NetworkOnMainThreadException
   at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1084)
   at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
   at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
   at java.net.InetAddress.getByName(InetAddress.java:295)
   at java.net.InetSocketAddress.<init>(InetSocketAddress.java:105)
   at java.net.InetSocketAddress.<init>(InetSocketAddress.java:90)
   at anywheresoftware.b4a.objects.SocketWrapper$UDPSocket$UDPPacket.Initialize2(SocketWrapper.java:421)
   at anywheresoftware.b4a.objects.SocketWrapper$UDPSocket$UDPPacket.Initialize(SocketWrapper.java:415)
   at com.x10.Home.main._send(main.java:3521)
   at com.x10.Home.main._btnevent_click(main.java:1302)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:158)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:154)
   at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:54)
   at android.view.View.performClick(View.java:3480)
   at android.view.View$PerformClick.run(View.java:13983)
   at android.os.Handler.handleCallback(Handler.java:605)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:4340)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
   at dalvik.system.NativeStart.main(Native Method)
android.os.NetworkOnMainThreadException
 
Upvote 0
Top