Page 4 of 11

Droid madness

It’s not original:) Made in China. Just bought in Taipei.

Some logging tips

If you don’t like use android debugger (because it is too slow on tablets or whatever) – you can use StackTraceElement to easily log your application activity.

You don’t need to put System.out in every method in your code. Just put LogUtils.trace() and you will know the exact method name and line of code.

Here’s simple sample LogUtils class:

package com.test.log;

// !!!!!
// NOTE: enabled log significantly reduces performance
// because it uses high cost getStackTrace() method, which produces huge amounts of objects
// !!!!!
public final class LogUtils {

	private static boolean sIsLogEnabled = true;
	private static String sApplicationTag = "LogDemo";

	private static final String TAG_FORMAT_METHOD = "%s:%s.%s:%d";
	private static final String FORMAT_METHOD_NAME = "%s:%d";

	private static StackTraceElement getCurrentStackTraceElement() {
		return Thread.currentThread().getStackTrace()[4];
	}

	public static void trace() {
		if (sIsLogEnabled) {
			android.util.Log.d(getMethodTag(getCurrentStackTraceElement()),
					getMethodName(getCurrentStackTraceElement()));
		}
	}

	private static String getMethodTag(StackTraceElement trace) {
		return String.format(TAG_FORMAT_METHOD, sApplicationTag,
				trace.getClassName(), trace.getMethodName(),
				trace.getLineNumber());
	}

	private static String getMethodName(StackTraceElement trace) {
		return String.format(FORMAT_METHOD_NAME, trace.getMethodName(),
				trace.getLineNumber());
	}

	public static void traceStack() {
		if (sIsLogEnabled) {
			traceStack(sApplicationTag, android.util.Log.ERROR);
		}
	}

	public static void traceStack(String tag, int priority) {
		if (sIsLogEnabled) {
			StackTraceElement[] stackTrace = Thread.currentThread()
					.getStackTrace();
			if (tag == null) {
				tag = getMethodTag(getCurrentStackTraceElement());
			}
			android.util.Log.println(priority, tag, stackTrace[4].toString());
			StringBuilder str = new StringBuilder();
			String prevClass = null;
			for (int i = 5; i < stackTrace.length; i++) {
				String className = stackTrace[i].getFileName();
				int idx = className.indexOf(".java");
				if (idx >= 0) {
					className = className.substring(0, idx);
				}
				if (prevClass == null || !prevClass.equals(className)) {
					str.append(className.substring(0, idx));
				}
				prevClass = className;
				str.append(".").append(stackTrace[i].getMethodName())
						.append(":").append(stackTrace[i].getLineNumber())
						.append("->");
			}
			android.util.Log.println(priority, tag, str.toString());
		}
	}

}

and simple Activity:

package com.test.log;

import android.app.Activity;
import android.os.Bundle;

public class LogDemoActivity extends Activity {

	private void methodB() {
		LogUtils.trace();
		LogUtils.traceStack();
	}

	private void methodA() {
		LogUtils.trace();
		methodB();
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		methodA();
	}
}

The output will be:

08-04 13:55:22.020: DEBUG/LogDemo:com.test.log.LogDemoActivity.methodA:13(31856): methodA:13
08-04 13:55:22.020: DEBUG/LogDemo:com.test.log.LogDemoActivity.methodB:9(31856): methodB:9

08-04 13:57:25.610: DEBUG/LogDemo:com.test.log.LogDemoActivity.methodA:14(31996): methodA:14
08-04 13:57:25.610: DEBUG/LogDemo:com.test.log.LogDemoActivity.methodB:9(31996): methodB:9
08-04 13:57:25.610: ERROR/LogDemo(31996): com.test.log.LogDemoActivity.methodB(LogDemoActivity.java:10)
08-04 13:57:25.610: ERROR/LogDemo(31996): LogDemoActivity.methodA:15->.onCreate:22->Instrumentation.callActivityOnCreate:1048->ActivityThread.performLaunchActivity:1715->.handleLaunchActivity:1767->.access$1500:122->.handleMessage:1005->Handler.dispatchMessage:99->Looper.loop:132->ActivityThread.main:4028->Method.invokeNative:-2->.invoke:491->ZygoteInit.run:844->.main:602->NativeStart.main:-2->

So you can easily trace:) Don’t forget to disable it for production.

//DL

gplus

another useless social stuff:)

If someone wants to follow me http://gplus.to/DmitryLukashev

//DL

Short Android links

Did you know that there are plenty of short urls for android.com web site? 🙂

http://a.android.com/ – ADK

http://b.android.com/ – bugz

http://d.android.com/ – developers portal

http://g.android.com/ – platform repo

http://m.android.com/ – I believe this is @android.com mail boxes

http://r.android.com/ – source patches reviews

http://tools.android.com/ – tools project

http://s.android.com/ – source page

//DL

Search icon style in Action Bar

Do you know that you can change menu icon style in honeycomb Action Bar?… and cannot do the same with search icon since last SDK tools update.

Join discussion here: https://groups.google.com/forum/?hl=en#!search/ActionBar$2FMode$20Style$20Regressions/flutuberwachung/KAamkrQ_6LI/K5dIort18eYJ

//DL

Horizontal slide gallery with pages

Imagine you want to create interactive horizontal slide gallery with paging (scroll left/right not one-by-one but pages).
Like this one:

Hopefully you can easily implement this with HorizontalScrollView. Since API level 3 it has method smoothScrollBy.

Your code may looks like:

public class TestUIActivity extends Activity {

	private GestureDetector gestureDetector = null;
	private HorizontalScrollView hs;

	private int mWidth = 1160;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		gestureDetector = new GestureDetector(new MyGestureDetector());
		hs = (HorizontalScrollView) findViewById(R.id.hs);
		hs.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (gestureDetector.onTouchEvent(event)) {
					return true;
				}
				if (event.getAction() == 1) {
					if (hs.getScrollX() > mWidth + mWidth / 2) {
						hs.smoothScrollBy(mWidth * 2 - hs.getScrollX(), 0);
					} else if (hs.getScrollX() > mWidth / 2) {
						hs.smoothScrollBy(mWidth - hs.getScrollX(), 0);
					} else {
						hs.smoothScrollBy(-hs.getScrollX(), 0);
					}
					return true;
				}
				return false;
			}
		});
	}

	class MyGestureDetector extends SimpleOnGestureListener {

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			if (e1.getX() < e2.getX()) {
				moveLeft();
			} else {
				moveRight();
			}
			return true;
		}
	}

	private void moveRight() {
		if (hs.getScrollX() > 0 && hs.getScrollX() < mWidth) {
			hs.smoothScrollBy(mWidth - hs.getScrollX(), 0);
		} else if (hs.getScrollX() > mWidth && hs.getScrollX() < mWidth * 2) {
			hs.smoothScrollBy(mWidth * 2 - hs.getScrollX(), 0);
		}

	}

	private void moveLeft() {
		if (hs.getScrollX() > 0 && hs.getScrollX() < mWidth) {
			hs.smoothScrollBy(-hs.getScrollX(), 0);
		} else if (hs.getScrollX() > mWidth && hs.getScrollX() < mWidth * 2) {
			hs.smoothScrollBy(mWidth - hs.getScrollX(), 0);
		}

	}
}

and simple layout that you may construct from code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<com.dlukashev.test.HorizontalScrollView
		android:id="@+id/hs"
		android:scrollbars="none"
		android:layout_width="1160dp"
		android:layout_height="wrap_content">
		<LinearLayout
			android:layout_width="wrap_content"
			android:layout_height="fill_parent">
			<!-- page1 -->
			<TextView
				android:id="@+id/id1"
				android:background="#FFFFFF"
				android:layout_marginLeft="10dp"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FFFFFF"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FFFFFF"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FFFFFF"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FFFFFF"
				android:layout_marginRight="20dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<!-- page2 -->
			<TextView
				android:background="#FF0000"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FF0000"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FF0000"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FF0000"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FF0000"
				android:layout_marginRight="20dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<!-- page3 -->
			<TextView
				android:background="#FFFF00"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FFFF00"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FFFF00"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FFFF00"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
			<TextView
				android:background="#FFFF00"
				android:layout_marginRight="10dp"
				android:layout_width="220dp"
				android:layout_height="220dp" />
		</LinearLayout>
	</com.dlukashev.test.HorizontalScrollView>
</LinearLayout>

One sad detail that you cannot change view animation speed (DEFAULT_DURATION=250 in class OverScroller). But you can easily fix it by adding HorizontalScrollView, OverScroller, Scroller and EdgeGlow to your project.

You can find full sample with animation speed = 500 here. This sample is for tablet resolution – change layout and items sizes for the phone if you would like.

//DL

View recycling in Gallery

Did you know that view recycling in Gallery is not implemented?

https://groups.google.com/forum/#!topic/android-developers/mpvkI_za25g

“This is a known “bug” (it’s not a bug really, we just never had the
time to implement recycling in Gallery) but we have no ETA for a fix.” (c) Romain Guy

Custom solution can be found here http://pastebin.com/FWyYTt4D (http://goo.gl/lm6st)

//DL

Java Bomb

That’s just brilliant!

http://thedailywtf.com/Articles/Disgruntled-Bomb-Java-Edition.aspx

//DL

Android tutorial slides

I would like to share some Android-related tutorial slides that we presented with Alexey in 2010 (http://habrahabr.ru/blogs/android/95250/) at St.Petersburg GTUG.

Some tips are still actual. So some of you could find it helpful;)

«Java and Android basics» (78 slides)

http://vk.amberfog.com/gtug/part1_Introduction2JavaAndroid_gtug.pdf

1.     Java and Android code style
2.     Java Collections
3.     Dalvik – Java Android VM
4.     Memory management in Java (GC + hard, soft, weak, phantom references)
5.     Java Exceptions handling
6.     Multithreading in Java
7.     Android Architecture
8.     Android entities: Activity, Service, Intent, BroadcastReceiver, ContentProvider
9.     Android Application, Context and Manifest
10.   Android System Services
11.   Android platform fragmentation and Java Reflection
12.   Saving state of application
13.   Android NDK
14.   Optimization for mobile: Design for better performance, responsiveness, seamlessness


«Android UI» (81 slides)

http://vk.amberfog.com/gtug/part2_WorkingWithAndroidUI_gtug.pdf

http://vk.amberfog.com/gtug/part2Examples.zip

1.     Activity lifecycle
2.     Activity, Layout, View, UI events, XML layouts
3.     XML layout’s types: FrameLayout, RelativeLayout, LinearLayout, TableLayout
4.     Layout tricks: merge, ViewStub, include
5.     Work with ListView and Adapters
6.     Menu & Dialogs
7.     UI thread! (and ANR)
8.     Developing custom UI-elements
9.     UI-development for difference screen resolutions and Android platform versions
10.   UI layout-tree analysis and optimization with special tools (hierarchyviewer, layoutopt)
11.   UI performance improvements
12.   UI guidelines
13.   Styles, Themes, Activity based dialogs
14.   Widgets, Live Folders, Live Wallpapers

«Android in Action» (69 slides).

http://vk.amberfog.com/gtug/part3_AndroidInAction_gtug.pdf

1.     Dealing with screen orientation change
2.     Possible causes of memory leaks: analysis and tools
3.     Data flow: Parcelable, Bundle, etc.
4.     android.app.Service
5.     Effective XML data parsing protocol
6.     Working with Databases
7.     Input Methods
8.     Search Providers
9.     Debugging hints & tools
10.   Battery life
11.   Usage statistics: Flurry
12.   Application signing and publishing

enjoy

//DL

playing with Arduino

Google I/O was awesome! 🙂

//DL

© 2020 Android Tales

Theme by Anders NorenUp ↑