Git Product home page Git Product logo

twitter-kit-android's Introduction

Twitter will be discontinuing support for Twitter Kit on October 31, 2018. Read the blog post here.

Twitter Kit for Android

Twitter Kit is a multi-module gradle project containing several Twitter SDKs including TweetComposer, TwitterCore, and TweetUi. Twitter Kit is designed to make interacting with Twitter seamless and efficient.

Twitter Kit Features

  • Display Tweets and timelines
  • Compose Tweets
  • Monetize with MoPub integration
  • Log in with Twitter
  • Access the Twitter API

Getting Started

Install using Bintray JCenter

Add twitter dependency to your build.gradle:

repositories {
  jcenter()
}

dependencies {
  compile('com.twitter.sdk.android:twitter:3.3.0@aar') {
    transitive = true
  }
}

Building from source

Rename samples/app/twitter.properties.sample to samples/app/twitter.properties and populate the consumer key and secret.

To build the entire project run

./gradlew assemble

Run all automated tests on device to verify.

./gradlew test connectedCheck

To run the sample app

./gradlew :samples:app:installDebug

Contributing

The master branch of this repository contains the latest stable release of Twitter Kit. See CONTRIBUTING.md for more details about how to contribute.

Code of Conduct

This, and all github.com/twitter projects, are under the Twitter Open Source Code of Conduct. Additionally, see the Typelevel Code of Conduct for specific examples of harassing behavior that are not tolerated.

Contact

For usage questions post on Twitter Community.

Please report any bugs as issues.

Follow @TwitterDev on Twitter for updates.

License

Copyright 2017 Twitter, Inc.

Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0

twitter-kit-android's People

Contributors

alxdroiddev avatar andypiper avatar dghubble avatar evansobkowicz avatar jonsnow21 avatar kellyschrock avatar kmandrika avatar pborreli avatar tearoom6 avatar toyamah avatar tyvsmith avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

twitter-kit-android's Issues

Integration alternatives

I was just wondering if there is anyone with an alternative implementation of Twitter Login rather than using this fabrics that requires you to go through a dozen of steps to import it to Android studio which doesn't work all the time.
Was also wondering why I need to have crashlytics setup in-order to use this lib to login to twitter.

IllegalArgumentException: column '_data' does not exist

  • Steps to reproduce the problem: Use AppCardBuilder#imageUri() with content Uri serviced by provider which does not expose _data column eg. FileProvider
java.lang.IllegalArgumentException: column '_data' does not exist
    at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
    at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:78)
    at com.twitter.sdk.android.tweetcomposer.FileUtils.resolveFilePath(FileUtils.java:87)
    at com.twitter.sdk.android.tweetcomposer.TweetUploadService.com.twitter.sdk.android.tweetcomposer.FileUtils.getPath(TweetUploadService.java:2062)
                                                             uploadAppCardTweet
                                                             onHandleIntent
    at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:145)
    at android.os.HandlerThread.run(HandlerThread.java:61)
  • Expected behavior: Mentioned Uris should work.
    As you see, _data column may not exist, image may even not be served from file. You should use appropriate ContentResolver methods to retrieve image content.
  • Android API Version: doesn't matter
  • Android Device: doesn't matter
  • Artifact Versions (run ./gradlew :app:dependencies):
+--- com.twitter.sdk.android:twitter:1.13.1
|    +--- com.digits.sdk.android:digits:1.10.3
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    \--- com.twitter.sdk.android:twitter-core:1.6.6
|    |         +--- com.squareup.retrofit:retrofit:1.8.0
|    |         |    \--- com.google.code.gson:gson:2.3
|    |         +--- io.fabric.sdk.android:fabric:1.3.10
|    |         \--- com.google.code.gson:gson:2.2.4 -> 2.3
|    +--- io.fabric.sdk.android:fabric:1.3.10
|    +--- com.twitter.sdk.android:tweet-composer:1.0.3
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    +--- com.twitter:twitter-text:1.13.0
|    |    \--- com.squareup.picasso:picasso:2.5.2
|    +--- com.twitter.sdk.android:tweet-ui:1.10.1
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    +--- com.android.support:support-v4:22.2.0 -> 23.3.0 (*)
|    |    +--- com.twitter.sdk.android:twitter-core:1.6.6 (*)
|    |    \--- com.squareup.picasso:picasso:2.5.2
|    \--- com.twitter.sdk.android:twitter-core:1.6.6 (*)

Allow easy display of Home Timeline with fabric

Feature Request
The core library includes a method named homeTimeline to allow fetching the homeTimeline for a user.
It would be great if you could add a matching class in Fabric that will give all the goodies of Timeline API for free.
If not, I would be happy to get your guidance to creating such class and maybe contribute it once it is ready

:-)

Thanks,
Amit

Failed to resolve: com.twitter.sdk.android:twitter:1.8.0

Hi there, i am trying to add the twitter sdk into my library in android. But, it is always said that failed to resolve the library. But if i tried to add the twitter sdk into my application (not library) it is ok.
Could you please help? Thanks.

Twitter kit assembleDebug fails

Twitter kit can't be built because FabricAndroidTestCase doesn't exist
/Users/icamacho/fabric/Twitter-Kit-Android/digits/src/debug/java/com/digits/sdk/android/DigitsAndroidTestCase.java
Error:(3, 36) error: cannot find symbol class TwitterAndroidTestCase
Error:(7, 44) error: cannot find symbol class FabricAndroidTestCase
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Inconsistent TwitterAuthClient#authorize() unhappy scenarios handling

  • Steps to reproduce the problem:
    Call TwitterAuthClient#authorize() and don't complete the flow successfully eg. disable internet connection before or cancel.
  1. when there is no internet connection at the beginning:

a) nothing is displayed
b) Callback.failure() is called with TwitterAuthException: Failed to get request token
c) resultCode in onActivityResult() is RESULT_FIRST_USER

  1. when back button was clicked:

a) Callback.failure() is called with TwitterAuthException: Authorization failed, request was canceled.
b) resultCode in onActivityResult() is RESULT_CANCELLED

  1. when cancel button was clicked:

a) Callback.failure() is called with TwitterAuthException: Failed to get authorization, bundle incomplete
b) resultCode in onActivityResult() is RESULT_FIRST_USER

  1. when internet connection is lost after WebView is displayed:

a) activity with WebView is finished immediately without any error message
b) Callback.failure() is called with TwitterAuthException: OAuth web view completed with an error
c) resultCode in onActivityResult() is RESULT_FIRST_USER

  • Expected behavior:
    If it is intended to not show any error to user from Twitter kit in some cases (like 1. and 4.) then callback parameters should allow developers to easily distinguish errors from cancellations so they can show their own UI. As you can see nor resultCode nor TwitterException can be used for that.
    If it is not intended then Twitter kit should always display something after calling TwitterAuthClient#authorize().
  • Android API Version: 21+
  • Android Device: all
  • Artifact Versions:
+--- com.twitter.sdk.android:twitter:1.13.1
|    +--- com.digits.sdk.android:digits:1.10.3
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    \--- com.twitter.sdk.android:twitter-core:1.6.6
|    |         +--- com.squareup.retrofit:retrofit:1.8.0
|    |         |    \--- com.google.code.gson:gson:2.3
|    |         +--- io.fabric.sdk.android:fabric:1.3.10
|    |         \--- com.google.code.gson:gson:2.2.4 -> 2.3
|    +--- io.fabric.sdk.android:fabric:1.3.10
|    +--- com.twitter.sdk.android:tweet-composer:1.0.3
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    +--- com.twitter:twitter-text:1.13.0
|    |    \--- com.squareup.picasso:picasso:2.5.2
|    +--- com.twitter.sdk.android:tweet-ui:1.10.1
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    +--- com.android.support:support-v4:22.2.0 -> 23.3.0 (*)
|    |    +--- com.twitter.sdk.android:twitter-core:1.6.6 (*)
|    |    \--- com.squareup.picasso:picasso:2.5.2
|    \--- com.twitter.sdk.android:twitter-core:1.6.6 (*)

Exception while fetching Tweet List by ids

07-05 16:35:13.484 5908-5908/ E/Twitter: API call failure.
                                                                    com.twitter.sdk.android.core.TwitterApiException: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 2740 path $.user.withheld_in_countries
                                                                        at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:378)
                                                                        at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
                                                                        at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
                                                                        at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
                                                                        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
                                                                        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                        at java.lang.Thread.run(Thread.java:818)
07-05 16:35:13.484 5908-5908/ E/TweetUi: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 2740 path $.user.withheld_in_countries
                                                                    com.twitter.sdk.android.core.TwitterApiException: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 2740 path $.user.withheld_in_countries
                                                                        at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:378)
                                                                        at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
                                                                        at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
                                                                        at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
                                                                        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
                                                                        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                        at java.lang.Thread.run(Thread.java:818)
07-05 16:35:13.484 5908-5908/ W/System.err: com.twitter.sdk.android.core.TwitterApiException: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 2740 path $.user.withheld_in_countries
07-05 16:35:13.484 5908-5908/ W/System.err:     at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:378)
07-05 16:35:13.484 5908-5908/ W/System.err:     at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
07-05 16:35:13.484 5908-5908/ W/System.err:     at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
07-05 16:35:13.484 5908-5908/ W/System.err:     at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
07-05 16:35:13.484 5908-5908/ W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
07-05 16:35:13.484 5908-5908/ W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-05 16:35:13.484 5908-5908/ W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
07-05 16:35:13.484 5908-5908/ W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
07-05 16:35:13.484 5908-5908/ W/System.err:     at java.lang.Thread.run(Thread.java:818)

Add Getting Started section in the doc

How should people use the kit and get started?

Essentially we should recommend them to go to the fabric website, sign up and/or modify their gradle/pom file

Make the interface LinkClickListener public

Using TweetView I noticed that I cant control where the links go.
Since getLinkClickListener is protected and overridable I believe that LinkClickListener should be a public interface I can implement.

Not sure if its possible just throwing out the idea, since I would like to open chrome tabs instead of chrome app when the user clicks links.

Thanks,
Manny

add Interceptors for okhttp client

Hi, I'm using this lib, is there any chance to add a interceptor for okhttp client, I want add a StethoInterceptor for network request debug

TweetView is throwing exception on Twitter object

TweetView is throwing error.
TweetView compactTweetView = new TweetView(context, tweet);

I have converted JSON into Twitter object but its throwing exception while using with TweetView.
Following TweetPojoActivity.java tutorial for conversion:
https://github.com/twitter/twitter-kit-android/blob/master/samples/app/src/main/java/com/example/app/tweetui/TweetPojoActivity.java

Exception Stack Trace:

07-06 01:19:46.790 25613-25613/ W/System.err: java.lang.NullPointerException: Attempt to read from field 'java.util.List com.twitter.sdk.android.core.models.VideoInfo.variants' on a null object reference
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.internal.TweetMediaUtils.getSupportedVariant(TweetMediaUtils.java:113)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.internal.TweetMediaUtils.hasSupportedVideo(TweetMediaUtils.java:93)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.BaseTweetView.setTweetMedia(BaseTweetView.java:706)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.BaseTweetView.render(BaseTweetView.java:478)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.TweetView.render(TweetView.java:65)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.BaseTweetView.setTweet(BaseTweetView.java:430)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.BaseTweetView.<init>(BaseTweetView.java:158)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.BaseTweetView.<init>(BaseTweetView.java:137)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.BaseTweetView.<init>(BaseTweetView.java:127)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.twitter.sdk.android.tweetui.TweetView.<init>(TweetView.java:32)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.xx.xxx.main.adapters.RecyclerviewHashtagListAdapter.onBindViewHolder(RecyclerviewHashtagListAdapter.java:112)
07-06 01:19:46.791 25613-25613/ W/System.err:     at com.xx.xx.main.adapters.RecyclerviewHashtagListAdapter.onBindViewHolder(RecyclerviewHashtagListAdapter.java:24)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5471)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5504)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4741)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4617)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1994)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1390)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1353)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:574)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3028)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2906)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3283)
07-06 01:19:46.791 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:596)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1695)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:122)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1192)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:814)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1187)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.792 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
07-06 01:19:46.793 25613-25613/ W/System.err:     at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2678)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.View.layout(View.java:16636)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.ViewGroup.layout(ViewGroup.java:5437)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1931)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.Choreographer.doCallbacks(Choreographer.java:670)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.Choreographer.doFrame(Choreographer.java:606)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.os.Looper.loop(Looper.java:148)
07-06 01:19:46.793 25613-25613/ W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
07-06 01:19:46.793 25613-25613/ W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
07-06 01:19:46.793 25613-25613/ W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
07-06 01:19:46.793 25613-25613/ W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Cannot resolve symbol XXXX

When using twitter-core and twitter as a module (didn't try the other ones), we get some "cannot resolve symbol..." for dependencies like Gson, Retrofit...
Note that, if we keep the imports, it's compiling fine.

Looks like it's only when using SDK 23.

See AppSession.java:

screen shot 2015-10-11 at 10 50 12

Tweets returned are null

  • Steps to reproduce the problem (include logs and/or sample code where appropriate):

Use the following class as an adapter for Recycler view:

public class TweetAdapter extends RecyclerView.Adapter<TweetAdapter.TweetViewHolder> {

    private static final int ITEMS_PER_RESULT = 10;
    private final TimelineDelegate<Tweet> tweetsDelegate;
    private final TweetsCallback cb;
    private final Context context;

    public TweetAdapter(Context ctx) {
        cb = new TweetsCallback();
        context = ctx;
        tweetsDelegate = new TimelineDelegate<>(new SearchTimeline.Builder()
                .query("%23twitterapi OR %23euro2016")
                .resultType(SearchTimeline.ResultType.RECENT)
                .maxItemsPerRequest(ITEMS_PER_RESULT)
                .build());
        tweetsDelegate.refresh(cb);
    }

    @Override
    public TweetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        CompactTweetView tv = new CompactTweetView(context, (AttributeSet) null);
        return new TweetViewHolder(tv);
    }

    @Override
    public void onBindViewHolder(TweetViewHolder holder, int position) {
        Tweet tweet = tweetsDelegate.getItem(position);
        holder.bind(tweet);
    }

    @Override
    public int getItemCount() {
        Log.d(MainActivity.TAG, String.valueOf(tweetsDelegate.getCount()));
        return tweetsDelegate.getCount();
    }

    @Override
    public void onRefresh() {
        tweetsDelegate.refresh(cb);
    }

    static final class TweetViewHolder extends RecyclerView.ViewHolder {

        public TweetViewHolder(CompactTweetView itemView) {
            super(itemView);
        }

        public void bind(Tweet tweet) {
            CompactTweetView tv = (CompactTweetView) itemView;
            tv.setTweet(tweet);
        }
    }

    private final class TweetsCallback extends Callback<TimelineResult<Tweet>> {

        @Override
        public void success(Result<TimelineResult<Tweet>> result) {
            notifyDataSetChanged();
        }

        @Override
        public void failure(TwitterException exception) {
        }
    }
}

And this is my Application class:

public class App extends Application {

    private static App singleton;
    private TwitterAuthConfig authConfig;

    public static App getInstance() {
        return singleton;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
        authConfig = new TwitterAuthConfig(BuildConfig.TWITTER_KEY,
                BuildConfig.TWITTER_SECRET);
        Fabric.with(this, new Twitter(authConfig));
    }
}

Upon running the app, I get NullPointerException

07-06 22:53:15.774 28176-28176/me.smac89.example E/AndroidRuntime: FATAL EXCEPTION: main
Process: me.smac89.example, PID: 28176
java.lang.IllegalArgumentException: Target must not be null.
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:618)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601)
at com.twitter.sdk.android.tweetui.BaseTweetView.setProfilePhotoView(BaseTweetView.java:676)
at com.twitter.sdk.android.tweetui.BaseTweetView.render(BaseTweetView.java:474)
at com.twitter.sdk.android.tweetui.CompactTweetView.render(CompactTweetView.java:63)
at com.twitter.sdk.android.tweetui.BaseTweetView.setTweet(BaseTweetView.java:430)
at me.smac89.example.navigation.adapter.TweetAdapter.onBindViewHolder(TweetAdapter.java:55)
at me.smac89.example.navigation.adapter.TweetAdapter.onBindViewHolder(TweetAdapter.java:24)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5471)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5504)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4741)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4617)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1994)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1390)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1353)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:574)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3028)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2906)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3283)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:596)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1732)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1497)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2678)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1931)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)

  • Expected behavior:
    The tweets returned by the TimelineDelegate should not be null
  • Android API Version:
    Version 23
  • Android Device (include Model and Manufacturer):
    Genymotion virtual device (2560x1800)
  • Artifact Versions (run ./gradlew :app:dependencies):
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile "com.android.support:appcompat-v7:${supportLibVersion}"
    compile "com.android.support:percent:${supportLibVersion}"
    compile "com.android.support:design:${supportLibVersion}"
    compile "com.android.support:support-v4:${supportLibVersion}"
    compile "com.android.support:cardview-v7:${supportLibVersion}"
    compile "com.android.support:recyclerview-v7:${supportLibVersion}"

    // ButterKnife ftw
    apt 'com.jakewharton:butterknife-compiler:8.1.0'
    compile 'com.jakewharton:butterknife:8.1.0'

    // Custom fonts
    compile 'com.vstechlab.easyfonts:easyfonts:1.0.0'

    // network
    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'

    // Tooltip
    compile 'com.github.michaelye.easydialog:easydialog:1.4'
    compile('com.twitter.sdk.android:twitter:1.14.1@aar') {
        transitive = true;
    }
}

Cannot create a class extending from BaseTweetView.

First of all, thank you for sharing this amazing kit.

I'm using this kit, and I'm trying to show a custom view using BaseTweetView.
But I cannot do.

Because BaseTweetView has two abstract methods that are package-private.
here

So I want to ask if their visibilities are by design.

  • If so, why is the class public visibility?
  • If not, could you expand the methods to protected?

Authorization via twitter oauth

There is a problem with authorization via twitter in android application imported into Fabric project connected as it is written in the docks, and hung their callbacks to get a token for use on the server. And like all good, even once it worked, but given the same token that has expired, and to them I can no longer use. I tried to remove the app, it is useless all exactly the same outdated token gives me. Here is the code that I'm trying to get the token:

Twitter.getSessionManager().clearActiveSession();
TwitterCore.getInstance().logIn(this, new com.twitter.sdk.android.core.Callback<TwitterSession>() {
    @Override
    public void success(Result<TwitterSession> twitterSessionResult) {
        String token = twitterSessionResult.data.getAuthToken().token;
        if (token != null) {
            authService(token, "twitter");
        } else {
            Toast.makeText(LoginActivity.this,
                    "Не удалось установить соеденения с Twitter", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void failure(TwitterException e) {
        Toast.makeText(LoginActivity.this,
                "Не удалось установить соеденения с Twitter", Toast.LENGTH_LONG).show();
    }
});

For information on the token I get using:
https://api.twitter.com/oauth/authorize?oauth_token=token
How can I fix it to always return a new token?

Loading image bug

My app is embedding tweet using Twitter UI.
And loading image in tweet, I have shown gray square at the upper left.

  • Steps to reproduce the problem: While loading image.
  • Expected behavior: I have shown gray square.
  • Android API Version: 23
  • Android Device: Nexus 5(Android 5.1), Nexus 5X(Android 6.0)

Below is screen shot,
2016-05-02 5 09 51

How to obtain logged user friends list?

Hey Guys,

I'm not really good on Java, but i need to obtain the friends list for a given user (i'm using phonegap and a custom plugin i'm developing)

I know i can create my own Custom API Client, and i did so:

class TwitterClientApiClient extends TwitterApiClient {
    public TwitterClientApiClient(TwitterSession session) {
        super(session);
    }

    public FriendsService getFriendsService() {
        return getService(FriendsService.class);
    }
}

interface FriendsService {
    @GET("/1.1/friends/list.json")
    void friends(@Query("user_id") long id,
                 @Query("screen_name") String screen_name,
                 @Query("cursor") Long cursor,
                 @Query("count") Integer count,
                 @Query("skip_status") boolean skip_status,
                 @Query("include_user_entities") boolean include_user_entities,
                 Callback<User> cb);
}

and the method that is calling the custom client is:

private void friends(final Activity activity, final CallbackContext callbackContext) {
        cordova.getThreadPool().execute(new Runnable() {
            @Override
            public void run() {

                TwitterClientApiClient twitterApiClient = new TwitterClientApiClient(Twitter.getSessionManager().getActiveSession());
                twitterApiClient.getFriendsService().friends(Twitter.getSessionManager().getActiveSession().getUserId(), null, null, 200, true, false, new Callback<User>() {
                    @Override
                    public void success(Result<User> userResult) {
                            callbackContext.success(handleFriendsResult(userResult.data));
                    }

                    @Override
                    public void failure(TwitterException e) {
                        Log.v(LOG_TAG, "Failed credentials verification");
                        callbackContext.error("Failed credentials verification");
                    }
                });
            }
        });
    }

I'm pretty sure that this will not work. I need a list of users, not a single User result... but really dont know what i should do.

Any help would be much appreciated.

Thanks in advance!

Twitter logIn exception

Currently twitter-kit internally use:

retrofit = 'com.squareup.retrofit:retrofit:1.6.1'
okHttp = 'com.squareup.okhttp:okhttp:2.0.0'
okHttpUrlConnection = 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'

and with that setup everything work.

In my project i use:

compile('com.twitter.sdk.android:twitter:1.7.0@aar') {
    transitive = true;
}
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0'
compile 'com.squareup.okhttp:okhttp:2.4.0'

and with this setup i get exception on login:

com.twitter.sdk.android.core.TwitterApiException: method POST must have a request body.
        at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:400)
        at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
        at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
        at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at retrofit.Platform$Android$2$1.run(Platform.java:142)
        at java.lang.Thread.run(Thread.java:818)

some changes to POST have been made in okhttp 2.3.0 -> 2.4.0 that don't allow POST without request body.

TwitterApiClient not extensible to add additional chunk Upload Media endpoints.

We can extend TwitterApiClient to add additional API endpoints but the same is not possible with Upload endpoints.

public MediaService getMediaService() { return getAdapterService(uploadAdapter,MediaService.class);}
Comparing it with:

protected <T> getService(Class <T> cls){ return getAdapterService(apiAdapter,cls); }

So, because of such structure how can we add additional upload endpoints to support multiple image upload using chunk upload endpoints as described over here

Also, when using enpoint provided by MediaService.class we can upload only single image(not multiple) ,right?
Sorry, if I am totally on the wrong page and not understanding the difference between single and chunk image uploads..

Add tweet composer initial text intent extra

Hi,

I noticed you guys removed tweet composer initial text intent extra in this commit:

885bcf1

I asked @dghubble about the reason and he gave me a very good explanation.(See comments in the commit) Just wondering if it's possible to add it back for developers like us? We really want to use Composer while adding some init text sometimes.

We understand if that cannot happen, if so, please advise if there's any good solution for us in this case. Thanks!

Looking forward to hearing from you soon!

Issue with OkHttp > 2.3.0 (method POST must have a request body)

I'm trying to integrate Digits in my app but with OkHttp > 2.3.0, I'm facing this error:

Twitter: Your app may not allow guest auth. Please talk to us regarding upgrading your consumer key.
com.twitter.sdk.android.core.TwitterApiException: method POST must have a request body.
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:400)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818)
Digits: HTTP Error: method POST must have a request body., API Error: 0, User Message: Try Again

Problem is located in OAuth2Service.OAuth2Api Retrofit interface where getGuestToken is a POST request with no body.

This is an old OkHttp problem and still in latest version.
Could it be possible to support more recent versions? (add an empty body for example)

Thanks.

Is there a way to convert JSON into Tweet Object

We are getting Twitter JSON response from server. But in Android, we are not able to convert JSON string directly into Tweet Object and use it. I know in iOS Twitter library, we have provision to covert JSON string to Tweet object

Is it something can be be done in future Or is there any existing solution for doing same thing?

Unknown error while loading Crashlytics settings

When initializing Fabric with Twitter kit only without Crashlytics enabled, the error from title is printed to the log. Here it is:
E/Fabric: Unknown error while loading Crashlytics settings. Crashes will be cached until settings can be retrieved.

  • Steps to reproduce the problem:
    Execute the following code (eg. from Application#onCreate()):
        TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY, TWITTER_SECRET);
        Fabric.with(this, new Twitter(authConfig)); //this is Application
  • Expected behavior: There should be no error and no interaction with Crashlytics.
  • Android API Version: 23
  • Android Device: probably all, eg. Nexus 5X
  • Artifact Versions:
+--- com.twitter.sdk.android:twitter:1.13.0
|    +--- com.twitter.sdk.android:tweet-composer:1.0.3
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    +--- com.twitter:twitter-text:1.13.0
|    |    \--- com.squareup.picasso:picasso:2.5.2
|    +--- io.fabric.sdk.android:fabric:1.3.10
|    +--- com.twitter.sdk.android:twitter-core:1.6.5
|    |    +--- com.squareup.retrofit:retrofit:1.8.0
|    |    |    \--- com.google.code.gson:gson:2.3
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    \--- com.google.code.gson:gson:2.2.4 -> 2.3
|    +--- com.twitter.sdk.android:tweet-ui:1.10.0
|    |    +--- io.fabric.sdk.android:fabric:1.3.10
|    |    +--- com.android.support:support-v4:22.2.0 -> 23.3.0 (*)
|    |    +--- com.twitter.sdk.android:twitter-core:1.6.5 (*)
|    |    \--- com.squareup.picasso:picasso:2.5.2
|    \--- com.digits.sdk.android:digits:1.10.0
|         +--- io.fabric.sdk.android:fabric:1.3.10
|         \--- com.twitter.sdk.android:twitter-core:1.6.5 (*)

Fabric Gradle plugin version: 1.21.6

java.lang.NoClassDefFoundError : Failed resolution of: Lretrofit/RestAdapter$Builder;

java.lang.NoClassDefFoundError: Failed resolution of: Lretrofit/RestAdapter$Builder;
                                                                 at com.twitter.sdk.android.core.internal.oauth.OAuthService.<init>(OAuthService.java:50)
                                                                 at com.twitter.sdk.android.core.internal.oauth.OAuth1aService.<init>(OAuth1aService.java:73)
                                                                 at com.twitter.sdk.android.core.identity.OAuthActivity.onCreate(OAuthActivity.java:69)
                                                                 at android.app.Activity.performCreate(Activity.java:5990)
                                                                 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
                                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
                                                                 at android.app.ActivityThread.access$800(ActivityThread.java:151)
                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
                                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                 at android.os.Looper.loop(Looper.java:135)
                                                                 at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                 at java.lang.reflect.Method.invoke(Method.java:372)
                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
                                                              Caused by: java.lang.ClassNotFoundException: Didn't find class "retrofit.RestAdapter$Builder" on path: DexPathList[[zip file "/data/app/com.dobanks-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
                                                                 at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                                                 at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                                                                 at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                                                                 at com.twitter.sdk.android.core.internal.oauth.OAuthService.<init>(OAuthService.java:50at com.twitter.sdk.android.core.internal.oauth.OAuth1aService.<init>(OAuth1aService.java:73at com.twitter.sdk.android.core.identity.OAuthActivity.onCreate(OAuthActivity.java:69at android.app.Activity.performCreate(Activity.java:5990at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387at android.app.ActivityThread.access$800(ActivityThread.java:151at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303at android.os.Handler.dispatchMessage(Handler.java:102at android.os.Looper.loop(Looper.java:135at android.app.ActivityThread.main(ActivityThread.java:5254at java.lang.reflect.Method.invoke(Native Methodat java.lang.reflect.Method.invoke(Method.java:372at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698Suppressed: java.lang.ClassNotFoundException: retrofit.RestAdapter$Builder
                                                                 at java.lang.Class.classForName(Native Method)
                                                                 at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
                                                                 at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
                                                                 at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
                                                                        ... 17 more
                                                              Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

Tried differt ways .. still getting same issue..but in my application i used retrofit 2.0.. works well.. but in twitter only it facing this issue
i attached my gradle file
build.txt

java.lang.NoClassDefFoundError: okio.Okio

It seems that there is a compatibility issue when using this kit alongside OkHttp & Okio? I'm getting NoClassDefFoundError when running my app. Any ideas to fix this?

API level : 16
Device : Xiaomi Redmi 2
Libs : OkHttp 2.5.0 & twitter.sdk.android:tweet-composer:1.0.3

Can't login using OAuth

Step to reproduce :

  1. Do not install twitter app to phone.
  2. Start using twitter login (button or manually with TwitterAuthClient)
  3. The OAuthActivity appears, do not enter anything, click to "Authorize app" button on web
  4. The web page redirect to another log in page (mobile version maybe), enter username and password, then click "Log In" button.
  5. The web page show 404 page, after debug I see that it was redirected to wrong url (https://mobile.twitter.com/https://api.twitter.com/oauth/authorize?oauth_token=xxxxxx)

Please fix this issue, thanks!

Advanced queries not working

I have been trying to work with advanced queries on the SearchTimeline and that doesn't seems to work, thing is, a query like this one #twitter near:"alabama" within:15mi won't return anything, but if you go to the advance search page of twitter it does returns some tweets.

Is there anything I'm missing? I have tried that with and without UTF-8 URL encoding and is just not working. Wondering if is on the API side...

Improper handling of ssl error

In OAuthWebViewClient.java

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        super.onReceivedSslError(view, handler, error);
        listener.onError(new WebViewException(error.getPrimaryError(), null, null));
    }

You should be either calling handler.proceed() if certificate meets your expectation otherwise calling handler.cancel().

This issue is holding us up from being able to submit to the app store.

OutOfMemoryErrors triggered by animated transition on ToggleImageButton "Like" button

I work on an app in which we use TweetViews in a RecyclerView. We have repeatedly observed the following crash: http://crashes.to/s/abe498ca58c

The crash is caused by an OutOfMemoryError which seems to occur when the 60 drawables for the animated transition on the "Like" button are loaded as part of the layout inflation of the ToggleImageButton. This probably only happens when memory pressure is already quite high, but weirdly we haven't seen other OutOfMemoryError crashes in this app.

Ironically (and frustratingly) our app does not even enable the tweet actions (i.e. tweetActionsEnabled in BaseTweetView always remains false), so this "Like" button with its fancy 60fps (total overkill if you ask me) animation is never even shown!

I think there must be way to achieve a similar animated transition using less memory-hungry means (animated vector drawables perhaps?). Also, would it be possible to offer a more lightweight (as in, non-animated, no hidden action bar views, etc.)?

Some more info:

  • Android API Version: >= 21 (v5.0.x)
  • Android Device (include Model and Manufacturer): Samsung gt_i9515, sm_g900f, sm_a300fu
  • Artifact Versions: com.twitter.sdk.android:twitter:1.13.1@aar

Thanks in advance.

Crashlytics Developer Tools Error

I am trying to compile the kit with Android Studio and this is what I get; any assistance please.

Information:Gradle tasks [:app:generateDebugSources, :app:generateDebugAndroidTestSources]
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAnimatedVectorDrawable2330Library UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72330Library UP-TO-DATE
:app:prepareComAndroidSupportDesign2330Library UP-TO-DATE
:app:prepareComAndroidSupportRecyclerviewV72330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportVectorDrawable2330Library UP-TO-DATE
:app:prepareComDigitsSdkAndroidDigits1103Library
:app:prepareComTwitterSdkAndroidTweetComposer103Library
:app:prepareComTwitterSdkAndroidTweetUi1101Library
:app:prepareComTwitterSdkAndroidTwitter1131Library
:app:prepareComTwitterSdkAndroidTwitterCore166Library
:app:prepareIoFabricSdkAndroidFabric1310Library
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:processDebugManifest
:app:fabricGenerateResourcesDebug
ERROR - Crashlytics Developer Tools error.
java.lang.IllegalArgumentException: Crashlytics found an invalid API key: null.
Check the Crashlytics plugin to make sure that the application has been added successfully!
Contact [email protected] for assistance.
at com.crashlytics.tools.android.DeveloperTools.processApiKey(DeveloperTools.java:375)
at com.crashlytics.tools.android.DeveloperTools.processProperties(DeveloperTools.java:515)
at com.crashlytics.tools.android.DeveloperTools.processArgsInternal(DeveloperTools.java:348)
at com.crashlytics.tools.android.DeveloperTools.gradleMain(DeveloperTools.java:292)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.invoke(StaticMetaMethodSite.java:46)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.call(StaticMetaMethodSite.java:91)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at com.crashlytics.tools.gradle.tasks.FabricTaskBuilder.callDevtoolsWrappingRuntimeExceptions(FabricTaskBuilder.groovy:327)
at com.crashlytics.tools.gradle.tasks.FabricTaskBuilder.this$2$callDevtoolsWrappingRuntimeExceptions(FabricTaskBuilder.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
at com.crashlytics.tools.gradle.tasks.FabricTaskBuilder$_pluginGenerateResources_closure4.doCall(FabricTaskBuilder.groovy:126)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
at groovy.lang.Closure.call(Closure.java:426)
at groovy.lang.Closure.call(Closure.java:442)
at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:554)
at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:535)
at org.gradle.api.internal.tasks.TaskMutator$1.execute(TaskMutator.java:77)
at org.gradle.api.internal.tasks.TaskMutator$1.execute(TaskMutator.java:73)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:62)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:154)
at org.gradle.internal.Factories$1.create(Factories.java:22)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:52)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:151)
at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:99)
at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:93)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:93)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:82)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:94)
at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:46)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:58)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:43)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:77)
at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:47)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:66)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:71)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:246)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
:app:fabricGenerateResourcesDebug FAILED
Error:Execution failed for task ':app:fabricGenerateResourcesDebug'.

Crashlytics Developer Tools error.
Information:BUILD FAILED
Information:Total time: 42.762 secs
Information:1 error
Information:0 warnings
Information:See complete output in console

Missing Quoted Tweet

Hi there.

I am creating an app using the lib.
And I noticed that Tweet model does not have quoted Tweet.

So would you add quoted Tweet to Tweet model?
Or could I send pull request?

TweetComposer should support Application context

This would crash if Builder is created using an application context instead of activity context with
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

 public Builder(Context context) {
            if (context == null) {
                throw new IllegalArgumentException("Context must not be null.");
            }
            this.context = context;
        }

public void show() {
            final Intent intent = createIntent();
            context.startActivity(intent);
}

Before calling startActivity(), you could check type of context and add the FLAG_ACTIVITY_NEW_TASK flag if needed.

Memory leak - context passed to TweetTimelineListAdapter.Builder()

Memory leak detection can be verified by adding Leak Canary library into project (https://github.com/square/leakcanary). It is easy to add, just one line of code in Application class.

Here is stack returned by Leak Canary:

D/LeakCanary: * com.example.activities.SocialMediaActivity has leaked:
D/LeakCanary: * GC ROOT static com.squareup.picasso.Picasso.singleton
D/LeakCanary: * references com.squareup.picasso.Picasso.targetToDeferredRequestCreator
D/LeakCanary: * references java.util.WeakHashMap.elementData
D/LeakCanary: * references array java.util.WeakHashMap$Entry[].[12]
D/LeakCanary: * references java.util.WeakHashMap$Entry.value
D/LeakCanary: * references com.squareup.picasso.DeferredRequestCreator.callback
D/LeakCanary: * references com.twitter.sdk.android.tweetui.BaseTweetView$PicassoCallback.this$0
D/LeakCanary: * references com.twitter.sdk.android.tweetui.CompactTweetView.mContext
D/LeakCanary: * leaks com.example.activities.SocialMediaActivity instance

I am adding UserTimeline as part of android.support.v4.app.Fragment that is a page in android.support.v4.view.ViewPager. Leaked Activity that holds ViewPager extends android.support.v7.app.AppCompatActivity. Leak is detected after calling SocialMediaActivity.onDestroy().

How I add timeline:

UserTimeline userTimeline = new UserTimeline.Builder().screenName(mTwitterUserName).maxItemsPerRequest(3).build();
TweetTimelineListAdapter adapter = new TweetTimelineListAdapter.Builder(getActivity()).setTimeline(userTimeline).build();
mListView.setAdapter(adapter);

Android 5.1.1 Nexus 4

+--- com.twitter.sdk.android:twitter:1.+ -> 1.14.0
|    +--- com.twitter.sdk.android:tweet-ui:1.11.0
|    |    +--- io.fabric.sdk.android:fabric:1.3.12
|    |    +--- com.twitter.sdk.android:twitter-core:1.7.0
|    |    |    +--- com.squareup.retrofit:retrofit:1.8.0
|    |    |    |    \--- com.google.code.gson:gson:2.3 -> 2.7
|    |    |    +--- io.fabric.sdk.android:fabric:1.3.12
|    |    |    \--- com.google.code.gson:gson:2.4 -> 2.7
|    |    +--- com.android.support:support-v4:23.1.1 -> 24.0.0 (*)
|    |    \--- com.squareup.picasso:picasso:2.5.2
|    +--- io.fabric.sdk.android:fabric:1.3.12
|    +--- com.digits.sdk.android:digits:1.11.0
|    |    +--- io.fabric.sdk.android:fabric:1.3.12
|    |    +--- com.twitter.sdk.android:twitter-core:1.7.0 (*)
|    |    +--- com.crashlytics.sdk.android:answers-shim:0.0.3
|    |    \--- com.squareup.retrofit:retrofit-mock:1.8.0
|    |         \--- com.squareup.retrofit:retrofit:1.8.0 (*)
|    +--- com.twitter.sdk.android:twitter-core:1.7.0 (*)
|    \--- com.twitter.sdk.android:tweet-composer:1.0.5
|         +--- com.twitter:twitter-text:1.13.0
|         +--- io.fabric.sdk.android:fabric:1.3.12
|         \--- com.squareup.picasso:picasso:2.5.2

I tried workaround by calling something like this in Fragment.onDestroy(), but it didn't work:

private void clearRequests(ViewGroup viewGroup) {
    for (int i = 0; i < viewGroup.getChildCount(); i++) {
        View item = viewGroup.getChildAt(i);
        if (item instanceof ViewGroup) {
            clearRequests((ViewGroup) item);
        } else if (item instanceof ImageView) {
            Picasso.with(getContext()).cancelRequest((ImageView) item);
        }
    }
}

If I understand correctly there are some Picasso requests still being executed after activity have been destroyed. As a solution maybe add some tags to each Picasso request: Picasso.with(getContext()).load(url).tag(tag).into(imageView); so they can be cancelled by Picasso.cancelTag(Object tag), e.g. for TweetTimelineListAdapter it might be UserTimeline object and you can add TweetTimelineListAdapter.cancelImageRequests() method thath could be called in onDestroy. If it won't help with memory leak it will at least help save some transfer - downloading pictures that will never be shown to user because parent activity have been destroyed;

As a side note please consider upgrading to Retrofit 2, so if someone is using up to date version of Retrofit, apk won't need to contain two versions of the same library.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.