Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StrictMode error - resource leak on 1.4.9 #963

Closed
toni1727 opened this issue Sep 20, 2015 · 20 comments
Closed

StrictMode error - resource leak on 1.4.9 #963

toni1727 opened this issue Sep 20, 2015 · 20 comments
Assignees
Labels
Milestone

Comments

@toni1727
Copy link

09-20 13:53:07.992  29298-29309/? E/StrictMode﹕ A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
    java.lang.Throwable: Explicit termination method 'close' not called
            at dalvik.system.CloseGuard.open(CloseGuard.java:184)
            at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:289)
            at cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:535)
            at cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:403)
            at cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:472)
            at cz.msebera.android.httpclient.conn.scheme.SchemeSocketFactoryAdaptor.connectSocket(SchemeSocketFactoryAdaptor.java:65)
            at cz.msebera.android.httpclient.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:177)
            at cz.msebera.android.httpclient.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:145)
            at cz.msebera.android.httpclient.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:131)
            at cz.msebera.android.httpclient.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:611)
            at cz.msebera.android.httpclient.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:446)
            at cz.msebera.android.httpclient.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:860)
            at cz.msebera.android.httpclient.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
            at com.loopj.android.http.AsyncHttpRequest.makeRequest(AsyncHttpRequest.java:146)
            at com.loopj.android.http.AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:177)
            at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:106)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
@toni1727 toni1727 reopened this Sep 20, 2015
@smarek
Copy link
Member

smarek commented Sep 20, 2015

What is it with you guys, always closing and reopening the issues immediately?

Anyway, I looked into this, and DefaultHttpClient in upstream version we do use, is extending AbstractHttpClient which is extending CloseableHttpClient

So the solution is to call .close() on underlying HttpClient instance for now.
When does this issue happen? Because I've tried all the samples and closing reopening the Sample application and I did not trigger this issue.

Thank you for report!

@smarek smarek added this to the 1.4.9.1 milestone Sep 20, 2015
@smarek smarek self-assigned this Sep 20, 2015
@toni1727
Copy link
Author

Where I have to call .close() ?

I call client.post in a Asynctask, in onPostexecute.
The call finish onsucess. Everything fine.

It happens when Android remove the Asynctask.

Best regards.

@toni1727
Copy link
Author

With SDK 22 and 1.4.8 Work without problems...

@smarek
Copy link
Member

smarek commented Sep 21, 2015

Close should be called when the original thread finishes, so the workaround is to init the AsyncHttpClient in ApplicationContext and call close() when application finishes. If it's created only within AsyncTask, you should call close() in onPostExecute

Yes, this is issue introduced by 1.4.9 version

@toni1727
Copy link
Author

AsyncHttpClient client = new AsyncHttpClient();
client.post(Config.server_url, params, new AlwaysAsyncHttpResponseHandler() {}
Client.close(); -> Doesn't exists!

and how init AsyncHttpclient in application context?

Thank you very much.

@smarek
Copy link
Member

smarek commented Sep 21, 2015

client.getHttpClient().close();
also note, you will not be able to use the same AsyncHttpClient instance again after calling close()

To init it within ApplicationContext, create instance in Application subclass and use it either statically (public static final AsyncHttpClient client = new AsyncHttpClient()) or access it through calling ((MyApplicationSubclassName)this.getContext().getApplicationContext())...

Regarding the second question, please consult Android Developer documentation and internet, you should know these things already.

@toni1727
Copy link
Author

I tried before

client.getHttpClient().close();

but it doesn't exits!

@smarek
Copy link
Member

smarek commented Sep 21, 2015

Sorry this is ugly ((DefaultHttpClient)client.getHttpClient()).close();

Returned is only of type HttpClient (only interface), however internally the type is DefaultHttpClient, which does have the method close()

@toni1727
Copy link
Author

Perfect, I use ((DefaultHttpClient)client.getHttpClient()).close(); OnSuccess and OnFailure.

Everything Works ok now.

Thank you very much again!

@smarek
Copy link
Member

smarek commented Sep 21, 2015

You're welcome

@toni1727 toni1727 reopened this Sep 21, 2015
@toni1727
Copy link
Author

Sorry again, but in Android 4.4.2 I receive this error:

java.lang.RuntimeException: android.os.NetworkOnMainThreadException
 android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1166)

when I close the Httpclient

((DefaultHttpClient) client.getHttpClient()).close();

@smarek
Copy link
Member

smarek commented Sep 21, 2015

Then do it in doInBackground, which is executed on another thread

@smarek smarek closed this as completed Sep 21, 2015
@toni1727
Copy link
Author

java.lang.IllegalArgumentException: Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead.

@smarek
Copy link
Member

smarek commented Sep 21, 2015

You're using the library wrong way, try to figure it out somehow. Also when you post errors, post a full stacktrace and relevant code please, I'm not going to guess what is the correct solution from your vaguely described situation.

@toni1727
Copy link
Author

I follow with your suggestions but give me another errors again and again. All problem started with the resource leak.

Anyway, this seems to work:

        if (android.os.Build.VERSION.SDK_INT > 9){
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                    .permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

Thank you very much again. I hope this helps to someone.

@smarek
Copy link
Member

smarek commented Sep 21, 2015

Disabling StrictMode is not helpfull, we use it as testing condition in our sample application. Synchronous ResponseHandler used in AsyncHttpClient error is coming from incorrect usage of library.

Also I don't see any reason why you're using AsyncHttpClient within AsyncTask, it'd be easier to use directly HttpClient in there, since you're already on different thread.

@toni1727
Copy link
Author

I use AsyncTask to get the data from Database and in onPostExecute I call AsyncHttpClient. You told me call AsyncHttpClient on doInBackground ...

Anyway I call in other places AsyncHttpClient without AsyncHttpClient and give me the same error.

That is how I have to call .close()

new Thread(new Runnable() {public void run() {((DefaultHttpClient) client.getHttpClient()).close();}}).start();

@smarek
Copy link
Member

smarek commented Sep 21, 2015

This library purpose is to provide seamless access to networking from Main Thread (UI Thread) from Activities, Fragments, Widgets, Views, ...

So I guess the best in context of Activity would be to create instance of AsyncHttpClient in Activity onCreate and then call stop() from onDestroy which ensures the client is always available and is disposed of correctly when bound Context is being removed from memory

Regarding the AsyncTask, if you do call .get() or other interface methods from doInBackground you're forcing Synchronous mode to the library, as the current thread is already different from Main/UI Thread.
So I guess calling the AsyncHttpClient from onPreExecute or onPostExecute is the best way.

Yes, putting the close() within new Thread is now requirement, or you can call the close() from doInBackground of AsyncTask

Sample task to close the client could be pretty simple, something like this:

class CloseHttpClientTask extends AsyncTask<HttpClient, Void, Void> {

        @Override
        protected Void doInBackground(HttpClient... params) {
            for(HttpClient hc : params){
                if(hc != null && hc instanceof Closeable){
                    try {
                        ((Closeable) hc).close();
                    }catch(Throwable ignored){
                    }
                }
            }
            return null;
        }
    }

Add logging if you need to.
And the call from anywhere would be like this:

new CloseHttpClientTask().execute(client.getHttpClient());

Which is probably bit more pretty than using raw Thread and Runnable

@toni1727
Copy link
Author

Thank you very much, I will take in account your suggestion when open and close the HttpClient.

@smarek
Copy link
Member

smarek commented Sep 22, 2015

Glad to help you out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants