androidiana
Alberto Souza


• @alberto_souza
• github.com/asouza
Parsear json

• Implementação padrão do
  Android(org.json)
• GSON
• Outros zilhões
try {

                  JSONObject imoveisComTotal = new


                       JSON-Java
JSONObject(imoveisJSON);

                      JSONArray jsonArrayDeImoveis = imoveisComTotal

                                  .getJSONArray("imoveis");



                      for (int i = 0; i < jsonArrayDeImoveis.length();
i++) {



                            JSONObject jsonObjectDoImovel = new
JSONObject(


jsonArrayDeImoveis.getJSONObject(i).toString());



                            JSONObject jsonImovel = new JSONObject(


jsonObjectDoImovel.getString("imovel"));

                        Imovel imovel =
criaImovelEmFuncaoDo(jsonImovel);
Braçal


• Deu trabalho então me entregue uma
  vantagem
GSON


private final static Gson gson = new Gson();

gson.toJson(serializable);
Justo

• Suporta as situações mais comuns
• Mas ainda achei meio lento
• Tem que ter o modelo compatível
Benchmarks

• Todos mentirosos :)
• https://github.com/eishay/jvm-serializers
• http://martinadamek.com/2011/01/31/comparison-
JACKSON


     ObjectMapper mapper = new ObjectMapper();

      TodosImoveis todosImoveis =
mapper.readValue(imoveisJSON,TodosImoveis.class);
• Suporta as situações mais comuns
• Mais fléxivel em relação ao mapeamento,
  atributo ou getter/setter
• Realmente foi mais rápido.
Fallback esperto
    @JsonAnySetter

    public void handleUnknown(String key, Object value)
{

         if (key.equals("fallback_url")) {

              this.linkOriginal = value.toString();

         }

    }
try{
                     Modo hard
                        JsonFactory f = new JsonFactory();

                      JsonGenerator g = f.createJsonGenerator(new
StringWriter());



                      g.writeStartObject();

                      g.writeObjectFieldStart("imovel");

                      g.writeStringField("titulo","Casa de praia em
salvador");

                      g.writeStringField("descricao", "Joe");


                      g.writeEndObject(); // for field 'name'


                      g.close(); // important: will force flushing
of output, close underlying output stream

              }
• Bem mais rápido
• Tem que ler na ordem dos campos do json
• Tudo braçal
• Como fazer os requests?
• Faz só o básico
• Tentativa de conexão não deu certo
Vai perder fácil?
• Pedir a resposta gzipada?
• Tempo máximo de espera
Deixar esperando
Feedback
                         try {

                              new
BuscaProximos(proximosFragment)


.buscaAPagina(calculaPaginaAtual());

                         } catch
(LocationProvidersOffException e) {

                              new
GPSAlert(proximosFragment).show();

                         }
• Configurações prontas
HttpConnectionParams.setSocketBufferSize(httpParams,
DEFAULT_SOCKET_BUFFER_SIZE);




                       Código
                    HttpProtocolParams.setVersion(httpParams,
HttpVersion.HTTP_1_1);

                    HttpProtocolParams.setUserAgent(httpParams,
String.format("android-async-http/%s (http://loopj.com/android-
async-http)", VERSION));



                    SchemeRegistry schemeRegistry = new
SchemeRegistry();

                    schemeRegistry.register(new Scheme("http",
PlainSocketFactory.getSocketFactory(), 80));

                    schemeRegistry.register(new Scheme("https",
SSLSocketFactory.getSocketFactory(), 443));

                    ThreadSafeClientConnManager cm = new
ThreadSafeClientConnManager(httpParams, schemeRegistry);



                    httpContext = new SyncBasicHttpContext(new
BasicHttpContext());

                    httpClient = new DefaultHttpClient(cm,
• Retry pronto
• Tempo máximo configurado
• GZIP
• Handler para binário
Simples de usar



          AsyncHttpClient client = new
AsyncHttpClient();

          client.get(url,tratadorDoRetorno);
Handler padrão

          DefaultRequestHandler<TodosImoveis>
imoveisEncontradosHandler = new
DefaultRequestHandler<TodosImoveis>() {



               @Override

               public void onSucess(TodosImoveis result)
{


BuscaPeloFiltroTask.this.onPostExecute(result);

               }



         //onError...
do android



public void execute(Integer... params) {

     enganaOCaraEUsaOutraLib(params);

}
Customizando


          AsyncHttpClient client = new
AsyncHttpClient();



          DefaultHttpClient defaultClient =
(DefaultHttpClient) client.getHttpClient();



          HttpRequestRetryHandler retryHandler =
defaultClient.getHttpRequestRetryHandler();



          client.get(url,handler);
Um pouco de
       performance


• Carregar imagens por exemplo
Cache


• Tamanho do cache
Problemas

• Expiração
• Memória
• Tamanho
Baseado no aparelho


• Cache pronto para usar nas apps android
LRUCache


          final int memClass = ((ActivityManager) this


.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryCl
ass();

          int memoryInBytes = 1024 * 1024 * memClass;

          final int cacheSize = memoryInBytes / 8;

          cache = new LruCache<String,Bitmap>(maxSize);
Tamanho das entradas
     do cache


• Como fazemos?
comportamento


             cache = new LruCache<String,Bitmap>(maxSize) {

                 protected int sizeOf(String key, Bitmap
bitmap) {

                      return bitmap.getByteCount();

                 };

            };
Pontos lentos


• Como descobrir?
App que consome
         serviço


• Vai olhar o serviço
Profile


• Vamos chorar
StrictMode

               StrictMode.setThreadPolicy(new
StrictMode.ThreadPolicy.Builder()

                       .detectDiskReads()

                       .detectDiskWrites()

                       .detectNetwork()

                       .penaltyLog()

                       .build());

               StrictMode.setVmPolicy(new
StrictMode.VmPolicy.Builder()

                       .detectLeakedSqlLiteObjects()

                       .detectLeakedClosableObjects()

                       .penaltyLog()

                       .build());
Reclamação
android.database.CursorWrapper.moveToFirst(CursorWrapper.java:65)

      04-05 11:07:54.598: E/StrictMode(6032):   at
android_maps_conflict_avoidance.com.google.common.android.AndroidConfi
g.getSetting(AndroidConfig.java:219)

      04-05 11:07:54.598: E/StrictMode(6032):   at
android_maps_conflict_avoidance.com.google.common.android.AndroidConfi
g.getDistributionChannelInternal(AndroidConfig.java:197)

      04-05 11:07:54.598: E/StrictMode(6032):   at
android_maps_conflict_avoidance.com.google.common.Config.init(Config.j
ava:273)

      04-05 11:07:54.598: E/StrictMode(6032):   at
android_maps_conflict_avoidance.com.google.common.android.AndroidConfi
g.<init>(AndroidConfig.java:100)

      04-05 11:07:54.598: E/StrictMode(6032):   at
android_maps_conflict_avoidance.com.google.common.android.AndroidConfi
g.<init>(AndroidConfig.java:87)

      04-05 11:07:54.598: E/StrictMode(6032):   at
com.google.android.maps.MapActivity.onCreate(MapActivity.java:419)

      04-05 11:07:54.598: E/StrictMode(6032):   at
android.support.v4.app.FragmentActivity.onCreate(Unknown Source)

      04-05 11:07:54.598: E/StrictMode(6032):   at
br.com.homehunter.infra.UseStorageFragmentActivity.onCreate(UseStorage
FragmentActivity.java:14)

      04-05 11:07:54.598: E/StrictMode(6032):   at
Mais profile


• Traceview
Marca os pontos


     public void buscaAPagina(int pagina) throws
LocationProvidersOffException{

           Debug.startMethodTracing("buscaPagina");

       //possivel código ruim aqui

       Debug.stopMethodTracing();

   }
Busca o arquivo



./adb pull /sdcard/buscaPagina.trace /tmp



./traceview /tmp/buscaPagina
Agora vai caçar
Comandos para o
      emulador


• DDMS/Emulator control
Mas...


• Já tentou controlar a bateria?
• E quando subiu o emulador com o tamanho
  errado
Chique


• Conectar no emulador via telnet
Comando
coisas a mais



power capacity 20


window scale 0.5
Valeu!
 @alberto_souza
github.com/asouza

Mobileconf dicas-android

  • 1.
  • 2.
  • 3.
    Parsear json • Implementaçãopadrão do Android(org.json) • GSON • Outros zilhões
  • 4.
    try { JSONObject imoveisComTotal = new JSON-Java JSONObject(imoveisJSON); JSONArray jsonArrayDeImoveis = imoveisComTotal .getJSONArray("imoveis"); for (int i = 0; i < jsonArrayDeImoveis.length(); i++) { JSONObject jsonObjectDoImovel = new JSONObject( jsonArrayDeImoveis.getJSONObject(i).toString()); JSONObject jsonImovel = new JSONObject( jsonObjectDoImovel.getString("imovel")); Imovel imovel = criaImovelEmFuncaoDo(jsonImovel);
  • 5.
    Braçal • Deu trabalhoentão me entregue uma vantagem
  • 6.
    GSON private final staticGson gson = new Gson(); gson.toJson(serializable);
  • 7.
    Justo • Suporta assituações mais comuns • Mas ainda achei meio lento • Tem que ter o modelo compatível
  • 8.
    Benchmarks • Todos mentirosos:) • https://github.com/eishay/jvm-serializers • http://martinadamek.com/2011/01/31/comparison-
  • 9.
    JACKSON ObjectMapper mapper = new ObjectMapper(); TodosImoveis todosImoveis = mapper.readValue(imoveisJSON,TodosImoveis.class);
  • 10.
    • Suporta assituações mais comuns • Mais fléxivel em relação ao mapeamento, atributo ou getter/setter • Realmente foi mais rápido.
  • 11.
    Fallback esperto @JsonAnySetter public void handleUnknown(String key, Object value) { if (key.equals("fallback_url")) { this.linkOriginal = value.toString(); } }
  • 12.
    try{ Modo hard JsonFactory f = new JsonFactory(); JsonGenerator g = f.createJsonGenerator(new StringWriter()); g.writeStartObject(); g.writeObjectFieldStart("imovel"); g.writeStringField("titulo","Casa de praia em salvador"); g.writeStringField("descricao", "Joe"); g.writeEndObject(); // for field 'name' g.close(); // important: will force flushing of output, close underlying output stream }
  • 13.
    • Bem maisrápido • Tem que ler na ordem dos campos do json • Tudo braçal
  • 14.
    • Como fazeros requests?
  • 15.
    • Faz sóo básico
  • 16.
    • Tentativa deconexão não deu certo
  • 17.
  • 18.
    • Pedir aresposta gzipada?
  • 19.
  • 20.
  • 21.
    Feedback try { new BuscaProximos(proximosFragment) .buscaAPagina(calculaPaginaAtual()); } catch (LocationProvidersOffException e) { new GPSAlert(proximosFragment).show(); }
  • 22.
  • 23.
    HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE); Código HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1); HttpProtocolParams.setUserAgent(httpParams, String.format("android-async-http/%s (http://loopj.com/android- async-http)", VERSION)); SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(httpParams, schemeRegistry); httpContext = new SyncBasicHttpContext(new BasicHttpContext()); httpClient = new DefaultHttpClient(cm,
  • 24.
    • Retry pronto •Tempo máximo configurado • GZIP • Handler para binário
  • 25.
    Simples de usar AsyncHttpClient client = new AsyncHttpClient(); client.get(url,tratadorDoRetorno);
  • 26.
    Handler padrão DefaultRequestHandler<TodosImoveis> imoveisEncontradosHandler = new DefaultRequestHandler<TodosImoveis>() { @Override public void onSucess(TodosImoveis result) { BuscaPeloFiltroTask.this.onPostExecute(result); } //onError...
  • 27.
    do android public voidexecute(Integer... params) { enganaOCaraEUsaOutraLib(params); }
  • 28.
    Customizando AsyncHttpClient client = new AsyncHttpClient(); DefaultHttpClient defaultClient = (DefaultHttpClient) client.getHttpClient(); HttpRequestRetryHandler retryHandler = defaultClient.getHttpRequestRetryHandler(); client.get(url,handler);
  • 29.
    Um pouco de performance • Carregar imagens por exemplo
  • 30.
  • 31.
  • 32.
    Baseado no aparelho •Cache pronto para usar nas apps android
  • 33.
    LRUCache final int memClass = ((ActivityManager) this .getSystemService(Context.ACTIVITY_SERVICE)).getMemoryCl ass(); int memoryInBytes = 1024 * 1024 * memClass; final int cacheSize = memoryInBytes / 8; cache = new LruCache<String,Bitmap>(maxSize);
  • 34.
    Tamanho das entradas do cache • Como fazemos?
  • 35.
    comportamento cache = new LruCache<String,Bitmap>(maxSize) { protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount(); }; };
  • 36.
  • 37.
    App que consome serviço • Vai olhar o serviço
  • 38.
  • 39.
    StrictMode StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .build());
  • 40.
    Reclamação android.database.CursorWrapper.moveToFirst(CursorWrapper.java:65) 04-05 11:07:54.598: E/StrictMode(6032): at android_maps_conflict_avoidance.com.google.common.android.AndroidConfi g.getSetting(AndroidConfig.java:219) 04-05 11:07:54.598: E/StrictMode(6032): at android_maps_conflict_avoidance.com.google.common.android.AndroidConfi g.getDistributionChannelInternal(AndroidConfig.java:197) 04-05 11:07:54.598: E/StrictMode(6032): at android_maps_conflict_avoidance.com.google.common.Config.init(Config.j ava:273) 04-05 11:07:54.598: E/StrictMode(6032): at android_maps_conflict_avoidance.com.google.common.android.AndroidConfi g.<init>(AndroidConfig.java:100) 04-05 11:07:54.598: E/StrictMode(6032): at android_maps_conflict_avoidance.com.google.common.android.AndroidConfi g.<init>(AndroidConfig.java:87) 04-05 11:07:54.598: E/StrictMode(6032): at com.google.android.maps.MapActivity.onCreate(MapActivity.java:419) 04-05 11:07:54.598: E/StrictMode(6032): at android.support.v4.app.FragmentActivity.onCreate(Unknown Source) 04-05 11:07:54.598: E/StrictMode(6032): at br.com.homehunter.infra.UseStorageFragmentActivity.onCreate(UseStorage FragmentActivity.java:14) 04-05 11:07:54.598: E/StrictMode(6032): at
  • 41.
  • 42.
    Marca os pontos public void buscaAPagina(int pagina) throws LocationProvidersOffException{ Debug.startMethodTracing("buscaPagina"); //possivel código ruim aqui Debug.stopMethodTracing(); }
  • 43.
    Busca o arquivo ./adbpull /sdcard/buscaPagina.trace /tmp ./traceview /tmp/buscaPagina
  • 44.
  • 45.
    Comandos para o emulador • DDMS/Emulator control
  • 46.
    Mas... • Já tentoucontrolar a bateria? • E quando subiu o emulador com o tamanho errado
  • 47.
    Chique • Conectar noemulador via telnet
  • 48.
  • 49.
    coisas a mais powercapacity 20 window scale 0.5
  • 50.