Little Experience on Solving Dex Method Count Limit

I have heard about the dex 65536 method count limit long time ago and I finally meet this problem recently. After digging around, I decided to strip off some unused method in an external jar, using jarjar.

Here are some little steps I used, using asmack jar as example.

Before fix

# convert jar to dex
>> $BUILD_TOOL_PATH/dx --dex --output asmack.dex asmack.jar
# method count
>> dex-method-count asmack.dex
5584
>> dex-method-count-by-package asmack.dex
...
113 com.novell
...
61  de.measite
...
1894    org.jivesoftware.smack
...
3585    org.jivesoftware.smackx
...
423 org.apachea
...

Create rule.txt with this line

zap org.jivesoftware.**

Run jarjar

# run modify jar
>> java -jar jarjar.jar process rule.txt asmack.jar asmack-modified.jar

# build dex file again
>> $BUILD_TOOL_PATH/dx --dex --output asmack-modified.dex asmack-modified.jar

# see the difference
>> dex-method-count asmack-modified.dex
554

Reference

Android OAuth With Signpost and Retrofit

This week I finally got time to play with square’s retrofit library. The first thing I wanted to try is to use it to for Twitter API. I immediately met a problem – how to do oauth? I was hoping retrofit would just work out of the box, but I can’t find any example in the site, and even not much results when google/stackoverflow around.

It seems that twitter4j provide full support of twitter api from oauth to getting posts, but as my goal is to try out retrofit, I decided not to use twitter4j at this point. Moreover, I will call different api later so it’s better for me to figure out how to do oauth on Android.

Scribe-java

I first found this Scribe java library, I like the way the author describe the library.

Who said OAuth was difficult? Configuring scribe is so easy your grandma can do it! check it out:

And it supports many existing oauth library including Google, Facebook, Yahoo, LinkedIn, Twitter, etc… It is easy to find example on integrating scribe with android. I tried this library and can successfully get pass the authorization steps, but one problem is that the library wrapped the request object so it may not work well with retrofit, I stopped here and did not dig deeper with this library even I like this a lot.

Signpost

Then I tried Signpost (github), this is a simple library that focus on signing the request and does not wrap request with custom object. Not like Scribe, Signpost does not implement any existing service, but implementing one is just providing the corresponding oauth api url.

1
2
3
4
5
6
7
OAuthConsumer consumer = new DefaultOAuthConsumer(
        API_KEY, API_SECRET);

OAuthProvider provider = new DefaultOAuthProvider(
        "https://api.twitter.com/oauth/request_token",
        "https://api.twitter.com/oauth/access_token",
        "https://api.twitter.com/oauth/authorize");

The Android integration of signpost is similar to scribe. After the authorization steps, it can hook into retrofit by extending the client.

Here is my code for integration – gist

Reference

Android XMPP Development

I was working on a chat feature on Android last two months using the aSmack library, here are some notes for future reference, although some detail may already not applicable for latest version of smack.

Smack

Smack is a library for communicating with XMPP servers to perform real-time communications, including instant messaging and group chat.

Extremely simple to use, yet powerful API. Sending a text message to a user can be accomplished in only a few lines of code

aSmack

buildsystem for Smack on Android

Integration

The sample code is very simple, just create a connection object, .connect(), .login(), create a chat object and send. But to integrate to Android, of course we need to do it in a background service, and here are the items I personally found difficult to handle well.

  • Handle connection state, connection listener seems not handle all connection events
  • May stuck in strange login state
  • User do action while connecting
  • Decide when to close the connection and stop background service
  • Smack does not have much doc
  • aSmack does not have doc at all
  • Smack is still in development
  • Not so extensible in some cases and it is hard to modify the library

Customized login method

If you customized the xmpp server to provide custom authenticate logic to integrate to external service, you can extends SASLMechanism in client side to support that. However, the authenticate call only accept jid and password parameter, and you may need to do some hack to pass more data to it if your authentication api required. Also, the response format of the login call is very limited, you cannot return extra customized error message so there may be some troubles when you want to have different handling on error cases in client side.

Customized IQ

Adding customized IQ is quite easy in smack, though you need it in a few places and may not work if you missed one. For one IQ type, you need to be clear on two things, the format you sent out and the format you receive. For the ease of development, you may want to put both implementation in one class, just make sure you don’t messed with it.

For sent out, you actually just need to construct the xml string and return in getChildElementXML(), no other setup needed.

For receiving IQ response, first you need to create IQProvider and add to ProviderManager, matching the xmlns in the query object. The IQProvider is used to convert the response packet to your customized IQ object. Then you need to extends PacketListener, and when you create the connection object, add the listener to it, with a PacketTypeFilter to match your IQ class. With both provider and listener setup correctly, you should be able to receive the response of the IQ.

XEP 0198 – stream management

I have no knowledge of XMPP before working on this project (actually still don’t know much about the protocol), but after implemented the basic program flow, we found that it is easy to trigger some message lost conditions. Turned out that xmpp is designed for stable network condition, so the support of mobile usage is actually quite bad.

An extension XEP 0198 is targeted for the message lost condition, I am not sure if it can really solve the problem, but at the time I started the development around end of July, XEP 0198 is not supported in Smack. The project seems quite active and the latest alpha version of Smack (4.0) seems included stream management but seems they have quite many changes and need some time to migrate from older version so I have not tried it yet. Also Smack 4.0 have Android support integrated so no need to use aSmack anymore.

Quick Look of Messaging App UI

I use messaging app everyday, whatsapp, Facebook messenger, gtalk, web and mobile. The UI of different apps looks natural to me and never tried to “see” the design of it.

Recently I am working on a messaging UI with a screenshot designer gave me. When I try to imagine how will this design looks like with real chat usage, I am sure there are lots of details not included in the design so I take a deeper look of the messaging app I used everyday.

When you received a message, you usually can see sender information (name / avatar), message content, and sent time. And for the message you send, you may also see deliver status (sent/fail/received/read), retry when fail.

Here are some elements besdies those basic thing.

Date header

To avoid displaying the date in every message, a common handling is to have a “Date header” to divide the messages, and whatsapp also added a sticky header for the date.

1-to-1 message VS group chat

In whatsapp 1-to-1, it only shows the name in action bar and does not include it in the content, it totally makes sense because you know who you are talking to when you are in that page. And for group chat, as more then one people you are talking to but the incoming messages are all aligned left, it is necessary to have the name before each message.

Facebook messenger also has similar logic of adding name but it is outside the bubble.

Message grouping

Most messaging app styled the messages with talk bubbles, it is interesting to see that some of them are not simply a bubble.

For Facebook messenger, I found that when continuous messages from same person is grouped, avatar is only showed once, in both 1-to-1 or group message. However, sometimes messages are not grouped, I guess it only groups messages within a short time.

For whatsapp, it groups continuous messages to one single bubble, my first reaction is it would be fun to write a list view adapter for that, need to have 3 item types for one message (start, middle, end) and the types may change when new messages come in, eg. end –> middle.

Understand what’s behind it

It is easy to reference other’s UI, but it is also important to understand why they handle information that way and even we will not handle like them, make sure we aware of it.

Y U NO Public (or Protected)

Recently started a new project in work so I finally have a chance to use SwipeRefreshLayout. The integration is very simple and does not change the structure of ListView like Android-PullToRefresh (I still love that library), so it should be easier to perform custom logic on the ListView afterwards.

I also like the progress bar embeded in the view very much, and would like to use it in other components to make my apps’s UI consistent. A quick look to the source code and found that it is implemented in the class SwipeProgressBar. It is sad that the class is not public and it seems there is no similar class in the framework and support library.

So, I just copy the code of SwipeProgressBar and BakedBezierInterpolator(required by SwipeProgressBar and also not public) myself and put it in my common lib, then use it in my app.

I understand that there are some kind of design principle of the class/methods visibility, but sometime it is quite frustrating that after going through the framework source code and found that you cannot to extend the class because some properties are private and does not have a public/protected getter.

Reference