Android Sample
https://github.com/antoniolg/DaggerExample
Sunday, November 6, 2016
Friday, June 10, 2016
Leakcanary - in progress
Disable InputMethodManager leak reporting
private RefWatcher install() { EnumSet<AndroidExcludedRefs> refs = EnumSet.of(AndroidExcludedRefs.SOFT_REFERENCES, AndroidExcludedRefs.INPUT_METHOD_MANAGER__ROOT_VIEW); return LeakCanary.install(this, DisplayLeakService.class, AndroidExcludedRefs.createBuilder(refs).build()); }
Friday, May 27, 2016
Getting started with Coredova
- Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine
- Chrome's V8 JavaScript engine: Google's open source high-performance JavaScript engine, written in C++ and used in Google Chrome, the open source browser from Google.
Programming Language : Javascript, HTML & CSS
Documentation https://cordova.apache.org/docs/
Change repositories from maven to jcenter
jcenter {
url "http://jcenter.bintray.com/"
}
jcenter {
url "http://jcenter.bintray.com/"
}
commands
cordova create hello com.example.hello HelloWorld
cordova platform add android --save
cordova platform ls
cordova build android
cordova create hello com.example.hello HelloWorld
cordova platform add android --save
cordova platform ls
cordova build android
cordova emulate --target=name_of_your_emulator android
reference:
create your first coredova app
npm ERR! code SELF_SIGNED_CERT_IN_CHAIN
Peer not authenticated
http://stackoverflow.com/questions/22887829/peer-not-authenticated-while-importing-gradle-project-in-eclipse
Thursday, March 31, 2016
Operating systems topics
Process, thread differences, PCB, TCB concepts
Deadlocks, scheduling, context switching
Virtual memory, physical memory, paging
Data sections (Text section, data section, BSS, Stack, Heap etc..) – Linker, Compiler jobs
Interrupts, polling, DMA etc..
Memory management, best fit, first fit etc...,
Processors and bus widths (data and address sizes)
Software engineering topics
basic definitions of CMM levels
Software Dev Life Cycle (SDLC) steps (requirements, design, implementation testing etc..)
Water fall, prototype, Iterative
basics of OO concepts (inheritance, encapsulation, asociation, aggregation polymorphism etc..)
Tools used for various phases of SDLC (static, run time analysis tools etc..)
Different kinds of testing (block-box, white-box, unit testing, integration testing etc..)
Tuesday, March 15, 2016
Android Testing
- JUnit 4 framework and tools provided by Google
Local Unit Tests
- These tests are compiled to run locally on the Java Virtual Machine (JVM) to minimize execution time. Use this approach to run unit tests that have no dependencies on the Android framework.
Instrumented Tests
- runs on an Android device or emulator.
- can be used for unit, user interface (UI), or app component integration testing.
- Building Instrumented Unit Tests:
- Automating User Interface Tests:
- Testing UI for a Single App
- Testing UI for Multiple Apps
- Testing App Component Integrations: Verify components such as Service, Content Provider
Espresso: UI testing frameworks, allows you to programmatically simulate user actions and test complex intra-app user interactions.
- can run on devices running Android 2.2 (API level 8) and higher.
Mockito:
Friday, March 11, 2016
Graph - Update In Progress
Dijkstra's algorithm:
- solves the single-source shortest-paths problem in edge-weighted digraphs with non-negative weights using extra space proportional to V and time proportional to E log V (in the worst case).
- Single-source shortest paths: O(E + V)
- solves the single-source problem in linear time.
- handles negative edge weights.
- Single-source longest paths: O(E + V)
- the concept of a shortest path is meaningless if there is a negative cycle.
- solves the single-source shortest-paths problem from a given source s
- finds a negative cycle reachable from s
- time proportional to E V and extra space proportional to V
- Solve all-pairs shortest path problem.
- Time proportional to V^3 and space proportional to V^2
MST(minimum spanning tree)
- A MST of an edge-weighted graph is a spanning tree whose weight (the sum of the weights of its edges) is no larger than the weight of any other spanning tree.
Thursday, March 10, 2016
RxJava/ RxAndroid
- Sample Code sample which replaces AsyncTaskLoader to load db data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private void loadDBData() { Observable.defer(new Func0<Observable<List<String>>>() { @Override public Observable<List<String>> call() { Log.d(TAG, "call " + Thread.currentThread().getName()); List<String> stringList = DBHelperUtil.getPasswordEntries(); return Observable.just(stringList); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this); } |
1 2 3 4 5 6 7 8 9 10 11 | @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List<String> strings) { } |
Tuesday, March 8, 2016
Working With databinding - TODO
http://prashamtrivedi.github.io/databinding
Wednesday, March 2, 2016
Securely store user credentials
- security is always a problem with rooted devices.
- always use encryption to store user’s credentials like User-name/Email Id or passwords
- AES Encyption can be done using below java packages
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
Ex: To Be Updated...
Tuesday, March 1, 2016
Popular Opensources used in Android
- AutoFitTextView: A TextView that automatically resizes text to fit perfectly within its bounds ( github )
- android-linear-layout-manager:
- Barber: https://github.com/hzsweers/barber
- Butterknife: https://github.com/JakeWharton/butterknife
- GoldenGate: https://github.com/Flipboard/GoldenGate
- Material Dialogs: https://github.com/afollestad/material-dialogs
- MaterialEditText: https://github.com/rengwuxian/MaterialEditText
- OkHttp: An HTTP & HTTP/2 client for Android and Java applications. https://github.com/square/okhttp
- Otto: An enhanced Guava-based event bus with emphasis on Android support https://github.com/square/otto
- RxJava: Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM. https://github.com/ReactiveX/RxJava
- RxAndroid: Reactive Extensions for Android https://github.com/ReactiveX/RxAndroid
- StickyListHeaders: an Android library that makes it easy to integrate section headers in your ListView https://github.com/emilsjolander/StickyListHeaders
- VerticalViewPager: https://github.com/castorflex/VerticalViewPager
- zxing: an open-source, multi-format 1D/2D barcode image processing library implemented in Java, with ports to other languages.
- DynamicGrid: Drag and drop GridView for Android.
- HockeySDK: Distribute beta versions, collect live crash reports, get feedback from real users and analyze test coverage.
- TextDrawable: provides images with letter/text
- TokenAutoComplete: Gmail style MultiAutoCompleteTextView for Android
- Rebound: a java library that models spring dynamics. Rebound spring models can be used to create animations that feel natural by introducing real world physics to your application.
- Android-betterpickers: Android library for better Picker DialogFragments https://github.com/code-troopers/android-betterpickers
- android-gif-drawable: Views and Drawable for displaying animated GIFs on Android https://github.com/koral--/android-gif-drawable
- Dagger: A fast dependency injector for Android and Java. https://github.com/square/dagger
- LoganSquare: Screaming fast JSON parsing and serialization library for Android. https://github.com/bluelinelabs/LoganSquare
- ANTLR:
- android-async-http: An asynchronous, callback-based Http client for Android built on top of Apache's HttpClient libraries.
- chat sdk - https://github.com/AppLozic/Applozic-Android-SDK
HTTP client vs HttpUrlConnection
Android provides two HTTP clients to perform network operations.
- Apache HTTP client
- HttpUrlConnection
- Large and extensive API's
- Supports cookie handling, authentication and connection management
- Suitable for web browser and other web applications
- Does not support HttpResponseCache mechanism, hence leading to increased network usage and battery consumption
- Light weight HTTP client
- Suitable for mobile applications
- Response caching reduce network use, improve speed and save battery.
- HttpURLConnection supported in Android from GB.
- HttpURLConnection is the best choice for Android.
Friday, February 19, 2016
Sorting & Searching - Update in progress
- MergeSort
- Time Complexity: Worse case - O(nLogn)
- Auxiliary Space: O(n)
- Application: Used in External Sorting
Fragment Android - Update In Progress
- Fragment is a small chunk of UI, process its own events and has its own lifecycle
- can be added/ removed in to activity
- Introduced in Honeycomb, but can be used from 1.6 using support library.
Need of Fragments
- Can combine several fragments in single Activity
- Fragments can be re-used across several activity
- Make use of larger screen
- Fragment Lifecycle
- Fragment & Activity combined Lifecycle
- Adding Fragment in to Activity
- XML
- runtime
- Inter Fragment communication pattern
- Managing fragment in backstack
- Fragments in ViewPager
- FragmentPagerAdapter
- FragmentStatePagerAdapter
- can be added/ removed in to activity
- Introduced in Honeycomb, but can be used from 1.6 using support library.
Need of Fragments
- Can combine several fragments in single Activity
- Fragments can be re-used across several activity
- Make use of larger screen
- Fragment Lifecycle
- Fragment & Activity combined Lifecycle
- Adding Fragment in to Activity
- XML
- runtime
- Inter Fragment communication pattern
- Managing fragment in backstack
- Fragments in ViewPager
- FragmentPagerAdapter
- FragmentStatePagerAdapter
Android Studio Tips
- Module build command
- gradlew build -p moduleA ( moduleA is the module subDirectory name )
Key Shortcuts
CTL + N - go to class
CTL + SHIFT + N - go to file
CTL + ALT+ SHIFT + N - go to symbol
ALT + Right/Left - go to next/previous editor
CTL + F12 - list class variables
SHIFT + F6 - rename
CTL + Y - delte line
CTL + ALT + M - extract method;
ALT + Delete - safe delete
ADB Commands
adb shell dumpsys meminfo package_name
adb shell ps | findstr -i search_string
adb shell pm list packages -f | findstr -i search_string
adb shell kill -3 PID
adb shell getprop | findstr -i prod
adb shell getprop | findstr -i ex
adb logcat -v time | findstr -i packagetest
apktool.bat d apk_path target_dir
dex2jar.bat apk_path
adb shell ps | findstr -i search_string
adb shell pm list packages -f | findstr -i search_string
adb shell kill -3 PID
adb shell getprop | findstr -i prod
adb shell getprop | findstr -i ex
adb logcat -v time | findstr -i packagetest
apktool.bat d apk_path target_dir
dex2jar.bat apk_path
Tuesday, February 9, 2016
Intent & Intent-Filters
Intent
Note: Beginning with Android 5.0 (API level 21), the system throws an exception if you call bindService() with an implicit intent.
Building an Intent
Using a Pending Intent
Intent Resolution
- TBU
- Messaging Object
- Can be used to request an action from another component.
- Facilitate communication between components in several ways.
- Start an activity.
- Start a service.
- Deliver a broadcast.
- Explicit intents: Specify the name by component class name. Can be used only to start a component in your own app.
- Implicit intents: Specify the general action to be performed, which allows component from other app to handle it.
Note: Beginning with Android 5.0 (API level 21), the system throws an exception if you call bindService() with an implicit intent.
Building an Intent
- Intent object carries information that the Android system uses to determine which component to start.
- Component Name: Name of the component, Optional for implicit intent but critical for explicit intent.
- Action Name : Specifies the generic action to perform.
- Data: The URI (a Uri object) that references the data to be acted on and/or the MIME type of that data
- Category: Additional information about the kind of component that should handle the intent
- Extras: Key-value pairs that carry additional information required to accomplish the requested action.
- Flag: flags instruct the Android system how to launch an activity.
- Declare intent filters for each of your app components with an <intent-filter> element in your manifest file.
- Each intent filter specifies the intent's action, data, and category.
- The system will deliver an implicit intent to your app component only if the intent can pass through one of your intent filters.
Using a Pending Intent
- PendingIntent object is a wrapper around an Intent object.
- Grants permission to other application use the contained Intent as it is executed from your own app process.
Intent Resolution
- TBU
Painless threading in Android UI
Main or UI thread:
- in charge of dispatching the events to the appropriate widgets & drawing event.
- ANR happens if UI thread blocked for more than 5 secs.
- the Android UI toolkit is not thread-safe and must always be manipulated on the UI thread.
- Activity.runOnUiThread(Runnable)
- View.post(Runnable)
- View.postDelayed(Runnable, long)
- Handler
Android Runtime (ART) Feature
Ahead-of-time compilation
ELF - Executable and Linkable Format.
Improved garbage collection
- At install time, ART compiles apps using the on-device dex2oat tool.
ELF - Executable and Linkable Format.
Improved garbage collection
- One GC pause instead of two
Google Cloud Messaging
Google Cloud Messaging for Android (GCM) is a service that allows you to send data from your server to your users' Android-powered device, and also to receive messages from devices on the same connection.
Steps to follow to receive GCM notification in Android Client App
1. Write Broadcast Receiver class which extends WakefulBroadcastReceiver and handle the intent action in onReceive method
Please refer below example
Declare the components in AndroidManifest.xml
GcmPushNotificationReceiver.java
GcmIntentService.java
Steps to follow to receive GCM notification in Android Client App
1. Write Broadcast Receiver class which extends WakefulBroadcastReceiver and handle the intent action in onReceive method
Please refer below example
Declare the components in AndroidManifest.xml
<!-- GCM Push Notification --> <!-- Broadcast Receiver to receive the GCM notification from GCM Agent --> <receiver android:name=".notification.GcmPushNotificationReceiver" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> </intent-filter> </receiver> <!-- Service to handle in intent action --> <service android:name="notification.GcmIntentService" > </service> <!-- GCM Push Notification -->
GcmPushNotificationReceiver.java
import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.support.v4.content.WakefulBroadcastReceiver; import android.util.Log; public class GcmPushNotificationReceiver extends WakefulBroadcastReceiver { private static final String TAG = GcmIntentService.class.getSimpleName(); @Override public void onReceive(Context context, Intent intent) { if(Debug.DEBUG_LOW) Log.i(TAG, "onReceive action = "+intent.getAction()); // Explicitly specify that GcmMessageHandler will handle the intent. ComponentName comp = new ComponentName(context.getPackageName(), GcmIntentService.class.getName()); // Start the service, keeping the device awake while it is launching. startWakefulService(context, (intent.setComponent(comp))); setResultCode(Activity.RESULT_OK); } }
GcmIntentService.java
import com.google.android.gms.gcm.GoogleCloudMessaging; import android.app.IntentService; import android.content.Intent; import android.os.Bundle; import android.util.Log; public class GcmIntentService extends IntentService { private static final String TAG = GcmIntentService.class.getSimpleName(); public GcmIntentService(String name) { super(name); } @Override protected void onHandleIntent(Intent intent) { Bundle extras = intent.getExtras(); GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); // The getMessageType() intent parameter must be the intent you received // in your BroadcastReceiver. String messageType = gcm.getMessageType(intent); if(Debug.DEBUG_LOW) Log.i(TAG, "GcmIntentService Received : (" +messageType+") "+extras.getString("title")); GcmPushNotificationReceiver.completeWakefulIntent(intent); } }
Customize volley default retry Policy & Cache timeout
Volley Default request retry policy:
/** The default socket timeout in milliseconds */
public static final int DEFAULT_TIMEOUT_MS = 2500;
/** The default number of retries */
public static final int DEFAULT_MAX_RETRIES = 1;
/** The default backoff multiplier */
public static final float DEFAULT_BACKOFF_MULT = 1f;
Volley does retry for you if you have specified the policy.
Client app can change retry values for each request using below API.
setRetryPolicy(new DefaultRetryPolicy (TIMEOUT_MS, MAX_RETRIES, BACKOFF_MULT ));
Example Timeout - 3000 secs, Num of retry - 2, Back Off Multiplier - 2
Attempt 1:
- time = time + (time * Back Off Multiplier );
- time = 3000 + 6000 = 9000
- Socket Timeout = time;
- Request dispatched with Socket Timeout of 9 Secs
Attempt 2:
- time = time + (time * Back Off Multiplier );
- time = 9000 + 18000 = 27000
- Socket Timeout = time;
- Request dispatched with Socket Timeout of 27 Secs
Steps to change Volley default Cache Hit & Cache time-out values:
1. Create new Volley Request class.
2. Set custom cacheHit & cacheTimeout values in parseNetworkResponse callback method.
Please refer below example.
GsonRequest.Java
HttpHeaderParser.java - only new method added
/** The default socket timeout in milliseconds */
public static final int DEFAULT_TIMEOUT_MS = 2500;
/** The default number of retries */
public static final int DEFAULT_MAX_RETRIES = 1;
/** The default backoff multiplier */
public static final float DEFAULT_BACKOFF_MULT = 1f;
Volley does retry for you if you have specified the policy.
Client app can change retry values for each request using below API.
setRetryPolicy(new DefaultRetryPolicy (TIMEOUT_MS, MAX_RETRIES, BACKOFF_MULT ));
Example Timeout - 3000 secs, Num of retry - 2, Back Off Multiplier - 2
Attempt 1:
- time = time + (time * Back Off Multiplier );
- time = 3000 + 6000 = 9000
- Socket Timeout = time;
- Request dispatched with Socket Timeout of 9 Secs
Attempt 2:
- time = time + (time * Back Off Multiplier );
- time = 9000 + 18000 = 27000
- Socket Timeout = time;
- Request dispatched with Socket Timeout of 27 Secs
Steps to change Volley default Cache Hit & Cache time-out values:
1. Create new Volley Request class.
2. Set custom cacheHit & cacheTimeout values in parseNetworkResponse callback method.
Please refer below example.
GsonRequest.Java
import java.io.UnsupportedEncodingException; import java.util.Map; import android.util.Log; import com.android.volley.AuthFailureError; import com.android.volley.DefaultRetryPolicy; import com.android.volley.NetworkResponse; import com.android.volley.ParseError; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; import com.android.volley.toolbox.HttpHeaderParser; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; import com.samsung.android.guardian.utils.Config; public class GsonRequest<T> extends Request<T> { private static final String TAG = GsonRequest.class.getSimpleName(); private final Gson gson; private final Class<T> clazz; private final Map<String, String> headers; private final Listener<T> listener; private int cacheHit; private int cacheExpiry; public GsonRequest(int method, String url, Class<T> clazz, Map<String, String> headers, Listener<T> listener, ErrorListener errorListener) { super(method, url, errorListener); //Using default volley retry policy //If retry policy has to be changed use setRetryPolicy methods from each request objects if(Config.VOOLEY_USE_DEFAULT_RETRY_POLICY){ setRetryPolicy(new DefaultRetryPolicy( DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); } GsonBuilder gsonBuilder = new GsonBuilder(); this.gson = gsonBuilder.create(); this.clazz = clazz; this.headers = headers; this.listener = listener; this.cacheHit = Config.DEFAULT_CACHE_HIT; this.cacheExpiry = Config.DEFAULT_CACHE_EXPIRY; } /** * @param method - GET/POST/PUT/DELETE * @param url - server URL * @param clazz - class represents server response * @param headers * @param listener - listener for success case * @param errorListener - listener for failure case * @param cacheHit - time milliseconds, after this time cache will be hit, but also refreshed on background. * 0 for CacheHit = CacheExpiry case * @param cacheExpiry - time milliseconds, after this time cache entry expires completely */ public GsonRequest(int method, String url, Class<T> clazz, Map<String, String> headers, Listener<T> listener, ErrorListener errorListener, int cacheHit, int cacheExpiry) { this(method,url, clazz, headers, listener, errorListener); this.cacheHit = cacheHit; this.cacheExpiry = cacheExpiry; } @Override public Map<String, String> getHeaders() throws AuthFailureError { return headers != null ? headers : super.getHeaders(); } @Override protected void deliverResponse(T response) { listener.onResponse(response); } @Override protected Response<T> parseNetworkResponse(NetworkResponse response) { try { String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); Log.i(TAG,"parseNetworkResponse data "+json); if(Config.VOOLEY_USE_DEFAULT_CACHE_TIMEOUT){ //Volley default Cache return Response.success(gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response)); }else{ // Apply custom cache return Response.success(gson.fromJson(json, clazz), HttpHeaderParser.parseIgnoreCacheHeaders(response, cacheHit, cacheExpiry)); } } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (JsonSyntaxException e) { return Response.error(new ParseError(e)); } } }
HttpHeaderParser.java - only new method added
public static Cache.Entry parseIgnoreCacheHeaders(NetworkResponse response, int cacheHit, int cacheExpiry) { long now = System.currentTimeMillis(); Map<String, String> headers = response.headers; long serverDate = 0; String serverEtag = null; String headerValue; headerValue = headers.get("Date"); if (headerValue != null) { serverDate = parseDateAsEpoch(headerValue); } serverEtag = headers.get("ETag"); final long ttl = now + cacheExpiry; final long softExpire; if(cacheHit > 0){ softExpire = now + cacheHit; }else{ softExpire = ttl; } Log.i(TAG, "parseIgnoreCacheHeaders softExpire: "+softExpire+", ttl:"+ttl); Cache.Entry entry = new Cache.Entry(); entry.data = response.data; entry.etag = serverEtag; entry.softTtl = softExpire; entry.ttl = ttl; entry.serverDate = serverDate; entry.responseHeaders = headers; return entry; }
AsyncTask
- Allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
- Should ideally be used for short operations. (use java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask for long running thread).
- Define 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
- Async Task uses ThreadPoolExecutor to run multiple tasks at same time. total thread size = CPU Count * 2 + 1.
- AsyncTask must be subclassed to be used.
- The task instance must be created on the UI thread.
- AsyncTask callback methods are thread safe.
AsyncTask<Params, Progress, Result>
params....
execute(params....) (ex: execute(url1, url2, url3))
- params are passed to doInBackground method which is being executed in worker thread
publishProgress(Progress...)
- being called inside doInBackground, Progress... value passed to method onProgressUpdate running in UI Thread.
- return result.... return value from doInBackground passed to onPostExecute
isCancelled()
- returns true is task been cancelled using API cancel(boolean)
- Before DONUT - no thread pool in AsyncTask
- After DONUT - Thread Pool introduced and by default task are executed in multiple thread.
- After HONECOMP - by default tasks are being executed in single thread to avoid error. use executeOnExecutor(Executor exec, Params... params) API to enable true parallel execution.
- AsyncTask has two static Executor instance SERIAL_EXECUTOR & THREAD_POOL_EXECUTOR
Subscribe to:
Posts (Atom)