While debugging my code in Android Studio, pressing F8 for Step Over launched iTunes.
The solution: navigate to System Preferences -> Keyboard -> Keyboard and tick the “Use all F1, F2 etc. keys as standard function keys”.
If you’re unfamiliar with using Android Studio and the IntelliJ IDEA interface, this page provides some tips to help you get started with some of the most common tasks and productivity enhancements.
[table id=1 /]
It is always useful to visit Android Studio -> Preferences -> Keymap for the full list of shortcuts
Tick Android Studio -> Preferences -> Editor -> General -> Appearance -> Show line number
The shell path for a user in OSX is a set of locations in the filing system whereby the user can use certain applications, commands and programs without the need to specify the full path to that command or program in the Terminal. This will work in all OSX operating systems.
You can find out whats in your path by launching Terminal in Applications/Utilities and entering:
echo $PATH
To make the new path stick permanently you need to create a .bash_profile file in your home directory and set the path there. This file control various Terminal environment preferences including the path.
nano ~/.bash_profile
Create the .bash_profile file with a command line editor called nano
export PATH="/Users/ofir/Library/Android/sdk/platform-tools:$PATH"
Add in the above line which declares the new location /Users/ofir/Library/Android/sdk/platform-tools as well as the original path declared as $PATH.
So now when the Terminal is relaunched or a new window made and you check the the path by
echo $PATH
You will get the new path at the front followed by the default path locations, all the time
/Users/ofir/Library/Android/sdk/platform-tools:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/git/bin
I’ve just bought a new ASUS ZenWatch and I’m working on a small application to extract the sensors data from the watch.
This post ( http://developer.android.com/training/wearables/apps/bt-debugging.html ) is describing the basic steps required to setup a device for debugging and to setup a debugging session. I’ve listed below some additional steps to help with the troubleshooting if things doesn’t work as planned.
Android Debug Bridge (adb) is a versatile command line tool that lets you communicate with an emulator instance or connected Android-powered device. It is a client-server program that includes three components:
Host: disconnected Target: connected
adb forward tcp:4444 localabstract:/adb-hub adb connect localhost:4444
Note: You can use any available port that you have access to.
Host: connected Target: connected
Well, this is the happy flow.
While debugging I’ve encountered some issues, especially after disconnecting the phone from the USB cable.
First, print a list of all attached emulator/device instances:
adb devices List of devices attached LGD855bxxxxx device
In this case you can see only the phone and not the watch, so you will need to execute
adb forward tcp:4444 localabstract:/adb-hub adb connect localhost:4444
In other cases you may get the error message
error: more than one device/emulator
You may need to terminates the adb server process:
adb kill-server
Now you can execute the adb forward and adb connect commands
adb forward tcp:4444 localabstract:/adb-hub adb connect localhost:4444
If you get an error message
error: device unauthorized.
Try revoking the permissions on the device – Developer options -> Revoke USB debugging authorizations. Then plug the device in and accept it again.
A BlockingQueue
is typically used to have on thread produce objects, which another thread consumes. Here is a diagram that illustrates this principle:
![]() |
A BlockingQueue with one thread putting into it, and another thread taking from it. |
The producing thread will keep producing new objects and insert them into the queue, until the queue reaches some upper bound on what it can contain. It’s limit, in other words. If the blocking queue reaches its upper limit, the producing thread is blocked while trying to insert the new object. It remains blocked until a consuming thread takes an object out of the queue.
The consuming thread keeps taking objects out of the blocking queue, and processes them. If the consuming thread tries to take an object out of an empty queue, the consuming thread is blocked until a producing thread puts an object into the queue.
BlockingQueue methods come in four forms, with different ways of handling operations that cannot be satisfied immediately, but may be satisfied at some point in the future: one throws an exception, the second returns a special value (either null or false, depending on the operation), the third blocks the current thread indefinitely until the operation can succeed, and the fourth blocks for only a given maximum time limit before giving up. These methods are summarized in the following table:
Throws exception | Special value | Blocks | Times out | |
Insert | add(e) |
offer(e) |
put(e) |
offer(e, time, unit) |
Remove | remove() |
poll() |
take() |
poll(time, unit) |
Examine | element() |
peek() |
not applicable | not applicable |
The code below defines an implementation of the BlockingQueue interface that works properly when accessed via multiple threads since it’s synchronized properly
class SimpleBlockingQueue<E> implements BlockingQueue<E> { /** * The queue consists of a List of E's. */ final private List<E> mList;
Add a new E to the end of the queue, blocking if necessary for space to become available
public void put(E e) throws InterruptedException { synchronized(this) { if (e == null) throw new NullPointerException(); // Wait until the queue is not full. while (isFull()) { // System.out.println("BLOCKING ON PUT()"); wait(); } // Add e to the ArrayList. mList.add(e); // Notify that the queue may have changed state, e.g., "no // longer empty". notifyAll(); } }
Remove the E at the front of the queue, blocking until there’s something in the queue
public E take() throws InterruptedException { synchronized(this) { // Wait until the queue is not empty. while (mList.isEmpty()) { // System.out.println("BLOCKING ON TAKE()"); wait(); } final E e = mList.remove(0); // Notify that the queue may have changed state, e.g., "no // longer full". notifyAll(); return e; } }
Starts a Thread for each element in the List of input Strings and uses Thread.join() to wait for all the Threads to finish. This implementation doesn’t require any Java synchronization mechanisms other than what’s provided by Thread
private volatile List<String> mInput = null; /** * The array of words to find. */ final String[] mWordsToFind; /** * The List of worker Threads that were created. */ private List mWorkerThreads;
Launch process for each and every string
// This List holds Threads so they can be joined when their processing is done. mWorkerThreads = new LinkedList(); // Create and start a Thread for each element in the // mInput. for (int i = 0; i < mInput.size(); ++i) { // Each Thread performs the processing designated by // the processInput() method of the worker Runnable. Thread t = new Thread(makeTask(i)); // Add to the List of Threads to join. mWorkerThreads.add(t); // Start the Thread to process its input in the background. t.start(); }
Barrier synchronization: using thread.join() to wait for the completion of all the other threads
// Barrier synchronization. for (Thread thread : mWorkerThreads) try { thread.join(); } catch (InterruptedException e) { printDebugging("join() interrupted"); }
If t
is a Thread
object whose thread is currently executing,
t.join();
causes the current thread to pause execution until t
‘s thread terminates.
Overloads of join
allow the programmer to specify a waiting period.
Like sleep
, join
responds to an interrupt by exiting with an InterruptedException
.
Initialization
private String TAG = "SensorCompass"; // Sensors & SensorManager private Sensor accelerometer; private Sensor magnetometer; private SensorManager mSensorManager; // Storage for Sensor readings private float[] mGravity = null; private float[] mGeomagnetic = null; // Rotation around the Z axis private double mRotationInDegress;
OnCreate
protected void onCreate(Bundle savedInstanceState) { // ... // Get a reference to the SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); // Get a reference to the accelerometer accelerometer = mSensorManager .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // Get a reference to the magnetometer magnetometer = mSensorManager .getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); // Exit unless both sensors are available if (null == accelerometer || null == magnetometer) finish(); }
Register this class as a listener for the accelerometer events and for magnetometer events:
@Override protected void onResume() { super.onResume(); // Register for sensor updates mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_NORMAL); }
The onPause method unregister this class as a listener for all sesnors
@Override protected void onPause() { super.onPause(); // Unregister all sensors mSensorManager.unregisterListener(this); }
The onSensorChanged method process the incoming sensors’ events
@Override public void onSensorChanged(SensorEvent event) { // Acquire accelerometer event data if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { mGravity = new float[3]; System.arraycopy(event.values, 0, mGravity, 0, 3); } // Acquire magnetometer event data else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { mGeomagnetic = new float[3]; System.arraycopy(event.values, 0, mGeomagnetic, 0, 3); } // If we have readings from both sensors then // use the readings to compute the device's orientation // and then update the display. if (mGravity != null && mGeomagnetic != null) { float rotationMatrix[] = new float[9]; // Users the accelerometer and magnetometer readings // to compute the device's rotation with respect to // a real world coordinate system boolean success = SensorManager.getRotationMatrix(rotationMatrix, null, mGravity, mGeomagnetic); if (success) { float orientationMatrix[] = new float[3]; // Returns the device's orientation given // the rotationMatrix SensorManager.getOrientation(rotationMatrix, orientationMatrix); // Get the rotation, measured in radians, around the Z-axis // Note: This assumes the device is held flat and parallel // to the ground float rotationInRadians = orientationMatrix[0]; // Convert from radians to degrees mRotationInDegress = Math.toDegrees(rotationInRadians); // Request redraw mCompassArrow.invalidate(); // Reset sensor event data arrays mGravity = mGeomagnetic = null; } } }