How to abort/interrupt a LocalServerSocket waiting, in a background thread, for a connection in method LocalServerSocker.accept() ?
I've tried to call close() method from another thread, but it does not seem to work.
There is a ticket opened for it in Android project: http://code.google.com/p/android/issues/detail?id=29939.
Seems the problem is confirmed by Google, as the first comment is:
i think we should rewrite this to use the same underlying libcore
stuff, and get the interruption behavior for free.
The workaround can be to send a custom shutdown command to the LocalServerSocket from another thread to unblock accept.
Instead of localSocket.close, use this: (requires API 21+)
try {
Os.shutdown(localSocket.fileDescriptor, OsConstants.SHUT_RDWR)
} catch (e: ErrnoException) {
if (e.errno != OsConstants.EBADF) throw e // suppress fd already closed
}
Related
I try to play some music for my activity but "sometimes" it throws exceptions below :
android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
This is my code that might be related on this error.
...
Thread thread = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bgm.start();
});
thread.start();
...
This code is in onCreate method and rest part is just make some animations with Handler or get 3 String intent values and five int intent values from previous activity.
It doesn't even tell me which line of my code it happened.
Thanks for reading my question.
Possible Solutions:
Override your service's onDestroy() method and watch what event flow leads to it. If you catch DeadObjectException without going through this method, your service should have been killed by the OS.
by removing Typeface, this might be because of ttf which I was using from the assets folder Please try comment the typeface and test it hope it will work for sure
put all your code inside the onCreate. From there you will see what is the culprit like a NullPointerException for example but your code will run smoothly already.
DeadObjectException: The object you are calling has died, because its
hosting process no longer exists.
I am connecting to an XMPP server in Android using Smack. Here is my code:
static void openConnection() {
try {
if (null == connection || !connection.isAuthenticated()) {
XMPPTCPConnectionConfiguration.Builder configuration = XMPPTCPConnectionConfiguration.builder();
configuration.setHost(SERVER_HOST);
configuration.setPort(SERVER_PORT);
configuration.setServiceName(SERVICE_NAME);
configuration.setUsernameAndPassword(new TinyDB(context.getApplicationContext()).getString("username"), new TinyDB(context.getApplicationContext()).getString("password"));
configuration.setDebuggerEnabled(true);
connection = new XMPPTCPConnection(configuration.build());
connection.setUseStreamManagement(true);
connection.setUseStreamManagementResumption(true);
ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(connection);
reconnectionManager.enableAutomaticReconnection();
reconnectionManager.setReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.RANDOM_INCREASING_DELAY);
connection.connect();
connection.login();
}
} catch (XMPPException xe) {
xe.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
So when I call openConnection() should I do that in an AsyncTask or is that not necessary? I am a little confused.
You should manage your XMPP(TCP)Connection within an Android Service. The service state (running/stopped) should reassemble the connection state: When the service is running the connection should be established or the service should try to establish the connection (if data connectivity is available). If the service stops, then also disconnect the connection.
When i call openConnection() should i do that in an asynctask or that is not neccesary?
Shortly, YES. Everything related with networking should be moved to another thread to avoid blocking main thread. Hence doInBackground() of AsyncTask runs on another thread, which is where you should call that function.
Yes, as the official documentation points it out:
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
I chose not to use AsyncTask for my smack project after searching around.
its threading model have been quite different between Android version and need to take care about, also after honeycomb, it is single thread, long blocking this will cause issue on the whole device that also use AsyncTask , xmpp and bosh can cause long blocking up to seconds/minutes
AsyncTask has implicit reference to activity and such a long operation will cause memory issues, or easy memory leakage when exception handling is not proper
AsyncTask 's result will be lost if reference activity got reset, but activity in Android can be reset as easy as a simple device rotation or network configuration change, too many save and restore instance to make this usable as every xmpp operation may be long task
I have being upgrading an application to use the new Mobile Android GNSK but I have noticed that using the new MusicID-Stream is a little bit tricky. If the "identifyAlbumAsync" method get executed before the "audioProcessStart" method(since this need to be executed in a different thread), the application just crashes. In the Gracenote Demo application, the "audioProcessStart" method is continuously running so there is no need to synchronize its execution with the "identifyAlbumAsync" method call. Is it the way it is supposed to be used? It will be convenient if the application didn't crashed at least when the methods are not executed in order. Also in our application, we don't want to have the "audioProcessStart" method continuously like it is done in the demo application. We only want to run the "audioProcessStart" method when the user request identification and when the song playing gets identified , we want to stop the audio processing by calling "audioProcessStop". Is there an easy way to do this? Right now, we are getting the Thread where "identifyAlbumAsync" is running to sleep for 2 seconds in order to make sure that the Thread where the "audioProcessStart" method is supposed to run has time to get executed. Thank you in advance for your prompt response
In the upcoming 1.2 release, IGnMusicIdStreamEvents includes a callback that signals audio-processing has started, and an ID can be synced with this, e.g.:
#Override
public void musicIdStreamProcessingStatusEvent( GnMusicIdStreamProcessingStatus status, IGnCancellable canceller ) {
if (GnMusicIdStreamProcessingStatus.kStatusProcessingAudioStarted.compareTo(status) == 0) {
try {
gnMusicIdStream.identifyAlbumAsync();
} catch (GnException e) { }
}
}
Thanks for the feedback, you're right about this issue. Unfortunately right now sleeping is the best solution. But we are adding support for an explicit sync event in an upcoming release, please stay tuned.
I've had in app billing v3 implemented in my app for about a week now. I used a lot of android's sample code to simplify the integration. I've been logging a crash fairly often that I can't seem to reproduce:
Exception Type: java.lang.RuntimeException
Reason: Unable to destroy activity {[package].billing.BillingActivity}: java.lang.IllegalArgumentException: Service not registered: [package].billing.util.IabHelper$1#40646a70
It seems to be breaking on this line:
if (mContext != null) mContext.unbindService(mServiceConn);
I'm binding this service in my onCreate method and disposing it in my onDestroy method (which is where this error is logged). Any pointers?
You could replace the line you mentioned:
if (mContext != null) mContext.unbindService(mServiceConn);
by this line
if (mContext != null && mService != null) mContext.unbindService(mServiceConn);
This should do the trick
I checked out the latest version of the sample project and up to today my recommendation is to currently to NOT use IabHelper. It is massively flawed.
To give you an idea:
1.) the async methods of IabHelper start a new thread. If IabHelper.dispose() is called while a thread is running you will always get various exceptions you cannot even handle.
2.) If the connection to the billing service goes down, they set it to null. But apart from that they never check if mService is null before accessing the methods. So it will always crash with NullPointerException in this case.
public void onServiceDisconnected(ComponentName name) {
logDebug("Billing service disconnected.");
mService = null;
and this is just the tip of the ice berg. Seriously I do not understand how somebody can publish this as reference code.
I just encountered the same issue but on android emulator. Billing v3 requires that Google Play app should be launched at least once and since the emulator lack of Google Play app it cannot set up helper and cannot dispose it in onDestroy().
My personal workaround is just skipping that error in try/catch:
#Override
protected void onDestroy() {
super.onDestroy();
if (bHelper != null){
try {
bHelper.dispose();
}catch (IllegalArgumentException ex){
ex.printStackTrace();
}finally{}
}
bHelper = null;
}
Add this in every onDestroy() where you dispose helper. Works fine for me.
The IabHelper class is working in a normal way.
What you need to do is:
when you call startSetup for the helper, you need to pass a callback IabHelper.OnIabSetupFinishedListener which will tell you the result of starting setup. If you get failure in the callback, the service connection with the google play services was not established.
You should handle future calls to IabHelper depending upon the result received in IabHelper.OnIabSetupFinishedListener. You can surely keep a boolean field to know what was the status.
The answer sam provided is actually a trick (in his own words). The helper classes aren't supposed to throw exceptions so that the user of those classes can implement some task in such scenarios.
And of-course, try/catch is best way if you don't want to go in details (whenever anything breaks due to exception, surely first thing which comes in mind is to put that in a try/catch block).
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);
}