Leak found: AndroidHttpClient created and never closed - android

I don't really instantiate an AndroidHttpClient anywhere in my code, but I do start a recognizer intent, which yields this exception at some point when my application runs:
Leak found
java.lang.IllegalStateException: AndroidHttpClient created and never closed
at android.net.http.AndroidHttpClient.<init>(AndroidHttpClient.java:152)
at android.net.http.AndroidHttpClient.newInstance(AndroidHttpClient.java:138)
at com.google.android.voicesearch.speechservice.SpeechServiceHttpClient.<init>(SpeechServiceHttpClient.java:59)
at com.google.android.voicesearch.speechservice.ServerConnectorImpl.<init>(ServerConnectorImpl.java:85)
at com.google.android.voicesearch.VoiceSearchContainerImpl.createRecognitionController(VoiceSearchContainerImpl.java:83)
at com.google.android.voicesearch.GoogleRecognitionService.onCreate(GoogleRecognitionService.java:65)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2066)
at android.app.ActivityThread.access$2500(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:993)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3835)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
at dalvik.system.NativeStart.main(Native Method)
Assuming the bug is not in Android's code but in mine, this leaked resource could have been created only in one of the following:
SpeechRecognizer.createSpeechRecognizer()
new RecognitionListener()
new Intent(SpeechRecognizer.RESULTS_RECOGNITION)
SpeechRecognizer.startListening(recognizerIntent)
But how do I know which one?

Assuming the bug is not in Android's code but in mine
The leak is in com.google.android.voicesearch, which is not your code.
If you can create a small sample project that demonstrates this leak, we can get an issue over to Google and hope that they will address it.

Why do you assume it's not in Android? SpeechRecognizer and RecognitionListener are in ASOP, so you can check (it's not there). Most probably SpeechServiceHttpClient uses an AndroidHttpClient internally. There is not much you can do but check you are calling all finalizer methods, if any (close(), shutdown(), etc), of the framework classes you are using.

Related

Error: Only one Looper may be created per thread with stacktrace that has no "Caused by:"

I'm using code from Extending the Service class to handle messaging in two Services and in another class (that's not a Service).
Below is the code that initializes and gets the suspicious objects (one thread each in onCreate() in the Services, and 2 threads in a static method in the other class). Nowhere is thread.run() explicitly called (as it shouldn't be, but I know that I can make the crash happen by calling it after calling thread.start() but not by calling thread.start() twice). While this code is taken from the Android documentation, I've only altered some of the variable names in my implementation. The same is true of the message-handling code that relies on this.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
Here's the stacktrace. Unfortunately, there's nothing indicating which implementation in my code is the offender, and I'm not able to reproduce the crash.
Fatal Exception: java.lang.RuntimeException: Only one Looper may be created per thread
at android.os.Looper.prepare(Looper.java:89)
at android.os.Looper.prepare(Looper.java:84)
at android.os.HandlerThread.run(HandlerThread.java:54)
06-15 06:23:18.599 27561-29056/? E/BluetoothBoundService﹕ Interrupted
read:
java.lang.InterruptedException
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:371)
at java.lang.Thread.sleep(Thread.java:313)
at services.BluetoothBoundService.receiveDataFromBT
(BluetoothBoundService.java:1442)
at
services.BluetoothBoundService.access$2700(BluetoothBoundService.java:147)
at services.BluetoothBoundService$9.run(BluetoothBoundService.java:1173)
at java.lang.Thread.run(Thread.java:761)
06-15 06:23:18.898 28954-28975/? E/BluetoothRemoteDevices﹕
state12newState1
06-15 06:23:23.469 27561-27570/? E/System﹕ Uncaught exception thrown by
finalizer
06-15 06:23:23.470 27561-27570/? E/System﹕ java.io.IOException: socket
not created
at android.net.LocalSocketImpl.shutdownInput(LocalSocketImpl.java:404)
at android.net.LocalSocket.shutdownInput(LocalSocket.java:207)
at android.bluetooth.BluetoothSocket.close(BluetoothSocket.java:575)
at android.bluetooth.BluetoothSocket.finalize(BluetoothSocket.java:273)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
at java.lang.Thread.run(Thread.java:761)
06-15 06:23:24.112 15861-15861/? E/SearchServiceStarter﹕ Task 174 failed
or timed out. Client 69758913221593243 disconnecting from SearchService!
java.util.concurrent.CancellationException: Task was cancelled.
at com.google.common.util.concurrent.d.ct(SourceFile:75)
at com.google.common.util.concurrent.d.get(SourceFile:57)
at com.google.common.util.concurrent.cg.n(SourceFile:2)
at com.google.common.util.concurrent.av.l(SourceFile:50)
at com.google.common.util.concurrent.ax.run(SourceFile:5)
at
com.google.android.apps.gsa.shared.util.concurrent.a.bc.run(SourceFile:2)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android....ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
06-15 06:23:24.144 15861-15861/? E/WorkerRegistryImpl﹕ getWorker() is
called after WorkerRegistry disposal.
06-15 06:23:24.153 15861-15861/? E/WorkerRegistryImpl﹕ getWorker() is
called after WorkerRegistry disposal.
06-15 06:23:34.229 15861-15861/? E/SearchServiceStarter﹕ Task 174 failed
or timed out. Client 69758913221593244 disconnecting from SearchService!
java.util.concurrent.CancellationException: Task was cancelled.
at com.google.common.util.concurrent.d.ct(SourceFile:75)
at com.google.common.util.concurrent.d.get(SourceFile:57)
at com.google.common.util.concurrent.cg.n(SourceFile:2)
at com.google.common.util.concurrent.av.l(SourceFile:50)
at com.google.common.util.concurrent.ax.run(SourceFile:5)
at
com.google.android.apps.gsa.shared.util.concurrent.a.bc.run(SourceFile:2)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(Zy
It seems that somehow and somewhy Android is calling thread.run() when it shouldn't be, but I don't know how to tell what's triggering that. I've looked at the other questions and answers that propose overriding run() to prevent this from happening (for example https://stackoverflow.com/a/24115631/1493426), but I don't see how to do that by extending HandlerThread in a reasonable way that won't have undesirable, unintended consequences.
For now I'm inclined to leave everyting alone, since the code has been around for at least several months, and this crash has only been seen once, but I'd like to know if there's a safe way to make the code more crash proof without hiding any underlying problems.

How to handle implementing different APIs for older and newer Android versions?

I am writing an app, which uses the older camera API for older android versions and the new camera2/torch API for API 23 and up.
Basically I determine once if the device is running a new enough Android version, and then switch between the implementations according to that. It boils down to this:
private static final int SDK_VERSION = Build.VERSION.SDK_INT;
private boolean isSdkVersionGreaterThanOrEqualTo(final int sdk) {
return SDK_VERSION >= sdk;
}
if (marshmallowOrNewer) { //isSdkVersionGreaterThanOrEqualTo(23);
try {
cameraManager.setTorchMode(cameraManager.getCameraIdList()[0], true);
} catch (final CameraAccessException e) {
e.printStackTrace();
}
} else {
cameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(cameraParameters);
camera.startPreview();
}
Upon running on Gingerbread I get a force close: FATAL EXCEPTION: main
java.lang.VerifyError
in this line:
toggleButton.setOnClickListener(new View.OnClickListener() {
which opens up the OnClickListener which contains above code and indicates that an API method is not supported in this version of android, which makes sense, but I'm not actually calling it here. How should I handle this situation properly, implementing different APIs for different Android versions, or how do I bypass this veryfication?
Stacktrace:
04-02 13:42:54.413 3815-3815/? E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.VerifyError: t.t.t.MainActivity$1
at t.t.t.MainActivity.onCreate(MainActivity.java:61)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
at android.app.ActivityThread.access$1500(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3835)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
at dalvik.system.NativeStart.main(Native Method)
I encountered this problem when adding Camera2 functionality to my app. I can't speak authoritatively about the underlying mechanism because I only fixed it through trial and error, but through testing I found that the problem only happens on devices earlier than Ice Cream Sandwich or so, after that it's possible to avoid it by doing run-time tests for the SDK version like you are doing. It seems that for ICS and later, it's okay to use an unsupported API in your class, as long as you never call it, but earlier than that you need to make sure you never instantiate a class that uses an unsupported API call, whether you call it or not.
I fixed the problem with this method:
Create a Camera2Object class (name it whatever you want) that calls the Camera2 API functions that you use. Remove all imports of Lollipop+ Camera2 classes from all other classes. It's ok to have a reference to this Camera2Object class in your other classes.
Only create an instance of this class after checking that the API version is >= 21 (Lollipop), or Marshmallow in your case.
In the class where you are currently calling the Camera2 functions inside an API version check if statement, change your code to check if your Camera2Object is not null and if so call a method on it that implements the functionality you had inside your if statement.
You might need to be a bit clever and rearrange your code so that all the Camera2 stuff is hidden inside this class - you might need to translate return codes etc into something that isn't dependent on Camera2 imports, and possibly return ints or Strings as references to Camera2 objects instead that get translated back and forth at the boundary between this class and the rest of your app.
You can have more than one class that calls Camera2 functions, as long as none of them are ever instances if the API version is less than 21.
This is tested on a 2.3.3 device, I can't vouch for earlier versions of Gingerbread. I also can't guarantee that you won't need to do this for ICS and after.

FATAL EXCEPTION: main java.lang.OutOfMemoryError

I keep getting this error when I run my app. The app will compile fine and interaction with the app is normal and until a certain period it will come up with the OUTOFMEMORY error message.
Error Logcat:
E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
at java.lang.StringBuilder.append(StringBuilder.java:216)
at org.json.JSONStringer.value(JSONStringer.java:249)
at org.json.JSONArray.writeTo(JSONArray.java:572)
at org.json.JSONStringer.value(JSONStringer.java:233)
at org.json.JSONObject.writeTo(JSONObject.java:671)
at org.json.JSONObject.toString(JSONObject.java:640)
at com.android.volley.toolbox.JsonObjectRequest.<init>(JsonObjectRequest.java:47)
at com.apps.robotapp.RobotService.onStart(RobotService.java:75)
at android.app.Service.onStartCommand(Service.java:450)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2833)
at android.app.ActivityThread.access$2000(ActivityThread.java:159)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1419)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
at dalvik.system.NativeStart.main(Native Method)
At Java:75 (RobotService:onStart) where the error occurs:
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,SPHERE_URL,obj,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//System.out.println("JsonObjectRequest:>>" + response + "<<");
System.out.println(response);
//hideProgressDialog();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//hideProgressDialog();
Runtime.getRuntime().gc();
}
}); queue.add(jsObjRequest);
I have implemented both system.gc() and Runtime.getRuntime().gc() into my implementation, however it still doesn't work.
Any idea how can I tackle this issue? Thanks
Without getting into the code.
You can follow ref count and RAM consumption :
http://developer.android.com/tools/debugging/debugging-memory.html
Btw. don't you have "Caused by..." in the exception log ?
Apart from using inordinate amounts of memory, this can happen when you leak memory. Leaking is unintentionally keeping references to objects that you do not need anymore.
There are many ways this can happen. The most obvious one is never clearing old items from a cache. In Android you can have Context related memory leaks, but that may not be the case for you.
Have a look at Google I/O 2011: Memory Management for Android Apps for a crash course on memory. In the video there's a link to the Eclipse Memory Analysis Tool (MAT) which can help you zoom in on the problem. Mastering this will likely take quite some time, so you may just want to watch the video to get an understanding of memory leaks and then using your common sense and knowledge of your app find the leak by reasoning. Good luck!

Android catching Exceptions

I have an exception that I'd like to handle, but I cannot tell its origin based on the stack trace (NsdManager.java:338 isn't mine and that files only has 58 lines). None of the files it references are mine.
Is there a way to handle any exception that comes up from the Handler?
E/AndroidRuntime﹕ FATAL EXCEPTION: NsdManager
java.lang.NullPointerException
at android.net.nsd.NsdManager$ServiceHandler.handleMessage(NsdManager.java:338)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
I am using a handler to help discover/rediscover a network based service when WiFi switches on and off.
Edit: Pastie of code
Full Stack Trace
MainActivity
NsdHelper
WifiBroadcastReceiver
WsHelper
NsdManager - Line 338 doesn't exist here, so I don't know what code to wrap in a Try/Catch.
Thanks
Turns out the NSD Manager has some long standing problems
https://code.google.com/p/android/issues/detail?id=35585
jmDNS works much better.

Android sometimes I get android.app.RemoteServiceException: Bad notification posted from package. Why?

I have a serius problem with my notification.
Sometimes when my app post the same custom notification I get this error:
android.app.RemoteServiceException: Bad notification posted from package com.packagename: Couldn't expand RemoteViews for: ClassName(package=com.packagename id=0 tag=null notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x22))
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1093)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3906)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:840)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:598)
at dalvik.system.NativeStart.main(Native Method)
What I have to do?
The notification contains only LinearLayout, TextViews and ImageViews and it works perfect most of the time.
There is a way to surround this error with try/catch so in this way android not stop my app?
Many thanks...
1) http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/app/ActivityThread.java#ActivityThread
From here we can see that this error can arise only in the one case:
case SCHEDULE_CRASH:
throw new RemoteServiceException((String)msg.obj);
2)http://openstorage.gunadarma.ac.id/android/sdk/sdk_310712/sources/android-15/android/app/ApplicationThreadNative.java
case SCHEDULE_CRASH_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
String msg = data.readString();
scheduleCrash(msg);
return true;
}
So this error arises from the ApplicationThreadNative
You can try to track ahead and maybe you will find the cause of this error.

Categories

Resources