I am trying to make a simple message application on Android with Apache Mina. I am getting IllegalStateException when calling connect(new InetSocketAddress(HOSTNAME, PORT)).
Here is my client code:
http://pastebin.com/NR2H6X0t
Here is my server code:
http://pastebin.com/Q5fQnu2p
And here is the logcat output:
http://pastebin.com/Egsh0Ce4
I am testing my apllications in same wifi network with a tablet and phone.
Even I can't see anything wrong with your code. But the LogCat says org.apache.mina.transport.socket.nio.NioSocketConnector.connect() of NioSocketConnector.java class at line# 185) your application is throwing NetworkOnMainThreadException. First fix that than check if you are getting the same error.
Apart from above I have a suggestion (for readability purpose): In connectToServerButtonClicked() of ClientActivity instead of using
for (; ; ) {
//rest of your code
}
better use
while(true){
//rest of your code
}
Edited: On request of #alkis coping my answer from comment below to answer part for better redability
NetworkOnMainThreadException : This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your network related code in AsyncTask.
Related
I want to make a request in my android app when the button is clicked. In Python I could do this like that:
import requests
params = {
'param1':some_string,
'param2':some_int,
'param3':another_string
}
requests.post("https://some.api.com/method/some.method", params=params)
I'd like to do the same in Kotlin when I push the button. I tried tp do this with Fuel and khhtp but didn't succeed much -- app crashed as soon as I pushed the button, responsible for sending request.
UPD: What I used:
AndroidManifest.xml
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
...
build.gradle
dependencies {
...
compile 'com.github.jkcclemens:khttp:0.1.0'
...
}
MainActivity.kt
fun request(){
var message = "message"
var uid = "123456" //I wanted to use it as int, but mapOf didn't allow me
var token = "token"
val payload = mapOf("token" to token, "user_id" to uid, "message" to message)
get("https://some.api.com/method/some.method", params=payload)
val popup = Toast.makeText(this,"Message sent!",Toast.LENGTH_LONG)
popup.show()
}
activity_main.xml
<Button
...
android:onClick="request" />
This is the example with khhtp, the one with Fuel is gone.
UPD2. Part of Logcat output:
You just need to look at the stack trace to find the issue. The code is throwing a NetworkOnMainThreadException. This happens when you try to access the network from within Android's main (often called UI) thread. This question have some good answers about this issue, however instead of trying to use AsyncTask make sure to read the documentation of your chosen network library and see how to make the call on a different thread.
I'm not sure if this is the root of your problem but your request method signature should be:
fun request(view: View)
{
}
As other members answered your code is calling network operation on main thread that's why it is crashing . You can avoid this either by using Kotlin Coroutines or by using methods of Anko Library (Which is officially supported by kotlin to simplify things in android). Here i just give a reference for how to do Async call in Anko.
doAsync {
// Call all operation related to network or other ui blocking operations here.
uiThread {
// perform all ui related operation here
}
}
To do it as Kotlin Coroutines, you can refer this answer:-
Kotlin Coroutines the right way in Android
I found the answer, basically what's happening is that you are not able to run internet connections at main thread, To override, add the following to the class where the user is performing network operations:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Reference (https://www.educative.io/edpresso/how-to-fix-androidosnetworkonmainthreadexception-error)
I am trying to add functionality to extract, decode, edit, encode and mux a video on Android. Therefore, I found some very useful implementation, which is part of the Android CTS ExtractDecodeEditEncodeMuxTest. Unfortunately, the code only works if it is executed as part of the testcase. I tried to execute it from a normal activity and get:
E/ExtractDecodeEditEncodeMuxTest (18781): java.lang.IllegalStateException:
Failed to stop the muxer
W/System.err(18781): java.lang.RuntimeException:
Surface frame wait timed out
W/System.err(18781): at ...OutputSurface.awaitNewImage(OutputSurface.java:216)
Any ideas, why the output surface does not receive the frames?
UPDATE:
Here are the log files for the working test case and the non-working implementation. The code for both is exactly the same. The only difference is that the working one is an AndroidTestCase and the other one is running in the application within an IntentService.
It seems that the whole thing stops extracting and decoding after about 6 frames. Any ideas?
Working Testcase Logoutput
Non-Working Log Output
morelikely you need to run it in separate thread
public static void runTest(ExtractDecodeEditEncodeMuxTest test) throws Throwable {
test.setOutputFile();
TestWrapper wrapper = new TestWrapper(test);
Thread th = new Thread(wrapper, "codec test");
th.start();
th.join();
if (wrapper.mThrowable != null) {
throw wrapper.mThrowable;
}
}
Thank's to fadden, I was able to resolve this issue. I am using an intent service now and start a thread without looper there, which works fine.
For running the code in an Android service, this means that the wrapping thread has to be started from a custom thread. Starting a thread within a thread is probably not the very best solution, but it actually solves the problem.
After many tries, I decided to ask the question again. In my last question, someone said I should have a look at Jsoup. I wrote some code but it won't work. It's an android app. But it totally crashes. with the error message:
Unfortunately, (appname) has stopped
See the full error message
My code for extracting text from the <div>:
public void ButtonClick(View view) throws IOException {
Document doc = dereference("here is my url");
String text = extractContent(doc);
updateUI(text);
}
private Document dereference(String uri) {
Connection connection = Jsoup.connect(uri);
return connection.get();
}
private String extractContent(Document doc) {
Elements divs = doc.select("div.onlinestatus");
return divs.text();
}
private void updateUI(String text) {
TextView tv = (TextView)findViewById(R.id.textView1);
tv.setText(text);
}
the input from the url:
<html><!-- [...] --><body>
<div class='onlinestatus'>Server ist online! <br /></div>
</body></html>
Can someone spot the mistake?
Edit: when I perform all these operations in a separate thread, I get a different error. Error log and code can be found here.
This is not a Jsoup question after all.
If you look up the error from your error log (first line) where it reads
NetworkOnMainThreadException
Googling for "android NetworkOnMainThreadException" yiedls a page from the android developer reference, which states
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
This would explain your previous attempts at moving code into a separate thread, which seemed to produce different results.
Have a look at the page suggested in the android developer reference, on Designing for Responsiveness. That should give you an answer.
The next thing that can fail, is that you need to do all UI changes in the thread that created the UI. The CalledFromWrongThreadException you got here tells you exactly what went wrong. Looking up that error will lead you to a question+answer similar to this one.
If you have problems with that, I suggest you ask a new question, if your problem is not already covered on StackOverflow (but I believe it is!)
Using Flex 4.5 for Android development, this is the script that should create the database:
private var db:File = File.userDirectory.resolvePath("events.db");
private var conn:SQLConnection;
public function MyDB() {
conn = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
conn.open(db, );
}
and I have added this permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
but I get this error:
SQLError: 'Error #3125: Unable to open the database file.', details:'Connection closed.', operation:'open', detailID:'1001'
at flash.data::SQLConnection/internalOpen()
at flash.data::SQLConnection/open()
at com.galleons.util::MyDB()[/Users/luca/Documents/Adobe Flash Builder 4.5/Galleons/src/com/galleons/util/MyDB.as:24]
I know it's an old question, but anyway I was facing the same error and found the cause. If any of the parent directories of File which you pass to SQLConnection.open() does not exist, Flash Player throws an Error with detailID=1001. Simply call dbFile.parent.createDirectory() and the error should be gone.
Similar answer was given on Adobe Forums: SQLError #3125
Have you checked the 'usual suspects'?
file exists
not locked by some other app / stale version of your app
path is correct
At least part of the problem is due to mixing the SQLConnection class's open() method – which is synchronous – with events that are only supposed to be used when opening an asynchronous connection. You would open an asynchronous connection by using the openAsync() method instead of the open() method.
The docs are contradictory in this matter because it is, in fact, possible to listen for SQLEvent.OPEN when opening a synchronous connection. However, notice that the SQLErrorEvent.ERROR listener is not being triggered in your code and you are instead getting a runtime error. The docs make no mention of SQLErrorEvent.ERROR working with a synchronous connection; that does appear to be the case.
It's possible this is an AIR bug, but I suspect mixing synchronous methods with asynchronous event listeners is just a gray area. It's also likely that the problem could be solved if you instead wrap the open() call in a try/catch block, which is the recommended way to catch synchronous errors:
try
{
conn.open(db);
trace("Hey, is that a database?", (db.exists));
}
catch (err:SQLError)
{
trace("Error, database not created:", err.message);
trace("Error details:", err.details);
}
I'm using addJavascriptInterface within my Android application to allow JavaScript to invoke functions I've created in my native Java application.
This worked well in Android 2.1, however in Android 2.2 I receive the error message "Error calling method on NPObject!"
When I instrument the method call the internals of the native method are getting called, however the exception is being throw in JavaScript.
I was getting this exact error:
Uncaught Error: Error calling method on NPObject!
Turns out I was attempting to invoke a JavascriptInterface function from a webview like so:
AndroidJS.populateField(field);
and on the Java side, the function didn't accept a parameter:
public void populateField() {}
Simply allowing the Java function to accept a parameter solved this error for me.
E.g.,
public void populateField(String field) {}
This may not be, and probably is not, the only reason this error could be thrown. This is simply how I resolved my specific scenario. Hope this helps! :)
OK, I have same problem as well, just in today.
What I did is putting code in UI Thread, like code below :
/**
* 給網頁Javascript呼叫的method
* Method for Javascript in HTML
* #param java.lang.String - Playlist ID
*/
public int callListByPID(final String pId)
{
Log.i(Constants.TAG, "PAD Playlist ID from HTML: "+pId);
runOnUiThread(new Runnable()
{
public void run()
{
// Put your code here...
}
});
return 1;
}
This solved my problem, and hope it can help some body... :-)
In my experience this problem is caused by Javascript interfaces bringing back objects that Javascript doesn't automatically identify.
In Android this is caused by wrappers like Boolean or Long in comparison to their native versions boolean and long.
//This will fail
public Long getmyLongVal() {
return 123456789;
}
//This will work
public long getMyNativeLongVal() {
return 123456789;
}
So remove your wrapper classes to any methods being used by Javascript if you want to avoid NPObject errors.
Here's a twist I found on this problem that could be useful for some of the folks running into this problem (and it likely explains intermittent failures that seem to defy explanation)...
If any exceptions are thrown (and not caught) in the return handler code prior to allowing the javascript interface callback to return clean, it will propagate back as a failed call and you will also get this error - and it would have nothing to do with missing functions or parameters.
The easiest way to find this case (whether or not you use this in your final implementation) is to push whatever handler code you have back onto the UI thread (the callback will not be on the UI thread) - this will allow the callback to return clean and any subsequent exceptions that occur will propagate properly up until you catch them or until the app crashes. Either way you will see exactly what is really happening. Otherwise the uncaught exception passes back to javascript where it will not be handled or reported in any way (unless you specifically built error trapping code into the JS you were executing).
Good Luck All.
bh
I had the same problem with Javascript-to-Java interface (WebView.addJavascriptInterface).
In Android 2.1 everything worked just fine but in Android 2.2 Javascript failed to call methods from this interface. It returned an error: Uncaught Error: Error calling method on NPObject!
It seems that on Android 2.2, the WebView has problem with Boolean data type returned from interface functions.
Changing:
public Boolean test_func() { return true; }
... to:
public int test_func() { return 1; }
... solved the problem.
This I believe is no longer supported anymore ( Always game NPObject error ) .
Please refer to the answer in this thread
Visit open an activity from a CordovaPlugin