Monday, 14 July 2014

When to join threads, concurrency, sequentially & When to join threads with CountDownLatch



Let's say I need to spawn multiple threads to do the work, and continue to the next step only after all of them complete. I will need to tell the main thread to wait. The key point is to use Thread.join() method. For example,


threadsJoinWithConcurrency();
textView.setText(threadNames.toString());

===========================================

public void threadsJoinWithConcurrency() {
List<Thread> threadList = new ArrayList<Thread>();

Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
 for (int i = 0; i < 1000000; i++) {
 i = i + 0;
}
threadNames.add("Thread-1");
}
});
threadList.add(t1);

Thread t2 = new Thread(new Runnable() {

@Override
public void run() {
for (int i = 0; i < 1000000; i++) {
  i = i + 0;
 }
 threadNames.add("Thread-2");
}
});
threadList.add(t2);

Thread t3 = new Thread(new Runnable() {
@Override
public void run() {

 for (int i = 0; i < 1000000; i++) {
  i = i + 0;
  }
 threadNames.add("Thread-3");
}
});
threadList.add(t3);

for (Iterator<Thread> iterator = threadList.iterator(); iterator.hasNext();) {
 Thread thread = iterator.next();
 thread.start();
}

for (Iterator<Thread> iterator = threadList.iterator(); iterator.hasNext();) {
 Thread thread = (Thread) iterator.next();
 try {
 thread.join();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 }
}


The output when running this program with 10 threads:

[Thread-1, Thread-3, Thread-2,]

The order in which the threads are executed is random, which is expected.

Also note that we use two for-loops, the first to create and start each thread, and the second loop to join each thread. If each thread is joined right after start, the effect is these threads are executed sequentially, without the desired concurrency. For example, the following code snippet results in serial execution:


threadsJoinWithSequentially();
textView.setText(threadNames.toString());

===================================

public void threadsJoinWithSequentially() {
List<Thread> threadList = new ArrayList<Thread>();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
 for (int i = 0; i < 1000000; i++) {
   i = i + 0;
 }
 threadNames.add("Thread-1");
}
});
threadList.add(t1);

Thread t2 = new Thread(new Runnable() {

@Override
public void run() {
   for (int i = 0; i < 1000000; i++) {
   i = i + 0;
  }
 threadNames.add("Thread-2");
}
});
threadList.add(t2);

Thread t3 = new Thread(new Runnable() {
@Override
public void run() {

for (int i = 0; i < 1000000; i++) {
 i = i + 0;
 }
 threadNames.add("Thread-3");
 }
 });
 threadList.add(t3);

for (Iterator<Thread> iterator = threadList.iterator(); iterator.hasNext();) {
 Thread thread = iterator.next();
 thread.start();
 try {
 thread.join();
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
}
}

Output:
[ Thread-1, Thread-2, Thread-3]

If we don't use any join at all, threadNames, when printed, may be empty, or partially filled, since the main thread will just move on when it gets the chance. The main thread will still wait, at the very last step, for all threads to complete, before exiting the JVM. The output for running 10 threads may be:

[Thread-1, Thread-2]

...

Thread.join() is used to wait for all child threads to complete. Now I will update it using CountDownLatch instead:

threadsJoinCountDownLatch();
textView.setText(threadNames.toString());

=====================================

public void threadsJoinCountDownLatch() {
List<Thread> threadList = new ArrayList<Thread>();
final CountDownLatch latch = new CountDownLatch(3);

Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
 for (int i = 0; i < 1000000; i++) {
   i = i + 0;
  }
  threadNames.add("Thread-1");
  latch.countDown();
  }
});
threadList.add(t1);

Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
 for (int i = 0; i < 1000000; i++) {
   i = i + 0;
 }
   threadNames.add("Thread-2");
   latch.countDown();
   }
});
threadList.add(t2);

Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
  for (int i = 0; i < 1000000; i++) {
    i = i + 0;
   }
   threadNames.add("Thread-3");
   latch.countDown();
  }
});
threadList.add(t3);

 for (Iterator<Thread> iterator = threadList.iterator(); iterator.hasNext();) {
   Thread thread = iterator.next();
   thread.start();
 }

 try {
   latch.await();
 } catch (InterruptedException e) {
   e.printStackTrace();
}
}

A CountDownLatch is created in main thread, passed to each child thread's constructor. Each child thread will count down by 1. After starting all child threads, the main thread then wait for the latch count to reach 0. To run it:
[ Thread-2, Thread-0, Thread-3]


I hope it will helpful :) Happpppy codddding :)



Thursday, 15 May 2014

Unique Device ID in Android

Hi
Today, I would like to share some piece of code which can be used as unique id in android

/**
 * Its nothing but combine the Android ID with the WiFi MAC address in a
 * method that generates a UUID: Required Permition : <uses-permission
 * android:name="android.permission.ACCESS_WIFI_STATE" />
 * 
 * @param activity
 * @return
 */
public static String getUniqueID(Activity activity) {
 final String macAddr, androidId;
WifiManager wifiMan = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInf = wifiMan.getConnectionInfo();

macAddr = wifiInf.getMacAddress();
androidId = "" + android.provider.Settings.Secure.getString(activity.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

String UUID = androidId.hashCode() + "" + macAddr.hashCode();

// Maybe save this: deviceUuid.toString()); to the preferences.
return UUID;
}
I hope this might useful for some cases, Happy Codding 

Thursday, 1 May 2014

Twitter Login and search using Twitter4j 4.0 jar

Twitter Sign In and search using Twitter4j 4.0 jar

Hi guys, today I am going to show you a very basic example of twitter sign In with Twitter4 jar,
In this example we can search tweets after sign In and we are just showing the name of user from twitter.

here very basic simple code of my main activity for simplicity i write complete code in Main Activity only.
MainActivity.Java


public class MainActivity extends Activity implements OnClickListener {
// Constants
Context context;
final String TAG = "TwitterSearch";

// buttons
Button btnLoginTwitterbtnLogoutTwitterbtnSearch;
EditText searchET;
TextView userNameTxt;

Twitter mTwitter;
ListView twitterList;

// Twitter
private static Twitter twitter;
private static RequestToken requestToken;

// Shared Preferences
private static SharedPreferences mSharedPreferences;

// Internet Connection detector

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

initializeUI();

if (android.os.Build.VERSION.SDK_INT > 9) {
/**
 * we should use Asynctask, But here we Just by pass NetworkOnMain
 * thread Exception
 */
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
}

loginCheck();

mTwitter = getTwitter();
}

/**
 * initialize variable and views
 */
private void initializeUI() {
context = getApplicationContext();

mSharedPreferences = getApplicationContext().getSharedPreferences(
"MyPref", 0);
// All UI elements
btnLoginTwitter = (Button) findViewById(R.id.btnLoginTwitter);
btnSearch = (Button) findViewById(R.id.btnSearch);
btnLogoutTwitter = (Button) findViewById(R.id.btnLogoutTwitter);
searchET = (EditText) findViewById(R.id.txtUpdateStatus);
userNameTxt = (TextView) findViewById(R.id.lblUserName);
twitterList = (ListView) findViewById(R.id.TweetlistView);
btnLogoutTwitter.setVisibility(View.GONE);
btnSearch.setVisibility(View.GONE);
searchET.setVisibility(View.GONE);
userNameTxt.setText("");

twitterList.setVisibility(View.GONE);

btnLoginTwitter.setVisibility(View.VISIBLE);
btnSearch.setOnClickListener(this);
/**
 * Twitter login button click event will call loginToTwitter() function
 * */
btnLoginTwitter.setOnClickListener(this);

/**
 * Button click event for logout from twitter
 * */
btnLogoutTwitter.setOnClickListener(this);
Log.e(TAG"Initialization Complete");

}

private Twitter getTwitter() {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey(getString(R.string.TWITTER_CONSUMER_KEY));
cb.setOAuthConsumerSecret(getString(R.string.TWITTER_CONSUMER_SECRET));

// Access Token
String access_token = mSharedPreferences.getString(
getString(R.string.PREF_KEY_OAUTH_TOKEN), "");
// Access Token Secret
String access_token_secret = mSharedPreferences.getString(
getString(R.string.PREF_KEY_OAUTH_SECRET), "");
cb.setOAuthAccessToken(access_token);
cb.setOAuthAccessTokenSecret(access_token_secret);

return new TwitterFactory(cb.build()).getInstance();
}

private void loginCheck() {
/**
 * This if conditions is tested once is redirected from twitter page.
 * Parse the uri to get oAuth Verifier
 * */
if (!isTwitterLoggedInAlready()) {
Uri uri = getIntent().getData();
if (uri != null
&& uri.toString().startsWith(
getString(R.string.TWITTER_CALLBACK_URL))) {
// oAuth verifier
String verifier = uri
.getQueryParameter(getString(R.string.URL_TWITTER_OAUTH_VERIFIER));

try {
// Get the access token
AccessToken accessToken = twitter.getOAuthAccessToken(
requestToken, verifier);

// Shared Preferences
Editor e = mSharedPreferences.edit();

// After getting access token, access token secret
// store them in application preferences
e.putString(getString(R.string.PREF_KEY_OAUTH_TOKEN),
accessToken.getToken());
e.putString(getString(R.string.PREF_KEY_OAUTH_SECRET),
accessToken.getTokenSecret());
// Store login status - true
e.putBoolean(getString(R.string.PREF_KEY_TWITTER_LOGIN),
true);
e.commit(); // save changes

Log.e("Twitter OAuth Token""> " + accessToken.getToken());

Log.e("Twitter OAuth Token sec",
"> " + accessToken.getTokenSecret());
// Hide login button
btnLoginTwitter.setVisibility(View.GONE);

// Show Update Twitter
searchET.setVisibility(View.VISIBLE);
btnSearch.setVisibility(View.VISIBLE);
twitterList.setVisibility(View.VISIBLE);
btnLogoutTwitter.setVisibility(View.VISIBLE);
userNameTxt.setVisibility(View.VISIBLE);

// Getting user details from twitter
// For now i am getting his name only
long userID = accessToken.getUserId();
User user = twitter.showUser(userID);
String username = user.getName();

// Displaying in xml ui
userNameTxt.setText(Html.fromHtml("<b>Welcome " + username
"</b>"));
Log.e(TAG"log In user : " + username);

catch (Exception e) {
// Check log for login errors
Log.e("Twitter Login Error""> " + e.getMessage());
}
}
}
}

/**
 * simply search the tweets query
 */
private void searchTweets() {
String query = searchET.getText().toString();
// Check for blank text

if (query.trim().length() > 0) {
List<Status> statuses = new ArrayList<Status>();
ArrayList<String> statusTexts = new ArrayList<String>();

try {
statuses = mTwitter.search(new Query(query)).getTweets();

for (Status s : statuses) {
statusTexts.add(s.getText() + "\n\n");
}
catch (Exception e) {
statusTexts.add("Twitter query failed: " + e.toString());
Log.e(TAG"Twitter query failed: " + e.toString());

}

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
statusTexts);
twitterList.setAdapter(adapter);
else {
// EditText is empty
Toast.makeText(getApplicationContext(),
"Please enter search query", Toast.LENGTH_SHORT).show();
}

}

/**
 * Function to login twitter
 * */
private void loginToTwitter() {
// Check if already logged in
if (!isTwitterLoggedInAlready()) {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(getString(R.string.TWITTER_CONSUMER_KEY));
builder.setOAuthConsumerSecret(getString(R.string.TWITTER_CONSUMER_SECRET));
Configuration configuration = builder.build();

TwitterFactory factory = new TwitterFactory(configuration);
twitter = factory.getInstance();

try {
requestToken = twitter
.getOAuthRequestToken(getString(R.string.TWITTER_CALLBACK_URL));
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse(requestToken.getAuthenticationURL())));
catch (TwitterException e) {
e.printStackTrace();

}
else {
// user already logged into twitter
Log.e(TAG"Already Logged into twitter");

Toast.makeText(getApplicationContext(),
"Already Logged into twitter", Toast.LENGTH_LONG).show();
btnLogoutTwitter.setVisibility(View.VISIBLE);
btnSearch.setVisibility(View.VISIBLE);
searchET.setVisibility(View.VISIBLE);
userNameTxt.setText("");
userNameTxt.setVisibility(View.VISIBLE);

twitterList.setVisibility(View.VISIBLE);

btnLoginTwitter.setVisibility(View.GONE);
}
}

/**
 * Check user already logged in your application using twitter Login flag is
 * fetched from Shared Preferences
 * */
private boolean isTwitterLoggedInAlready() {
// return twitter login status from Shared Preferences
return mSharedPreferences.getBoolean(
getString(R.string.PREF_KEY_TWITTER_LOGIN), false);
}

/**
 * Function to logout from twitter It will just clear the application shared
 * preferences
 * */

private void logoutFromTwitter() {
// Clear the shared preferences
Editor e = mSharedPreferences.edit();
e.remove(getString(R.string.PREF_KEY_OAUTH_TOKEN));
e.remove(getString(R.string.PREF_KEY_OAUTH_SECRET));
e.remove(getString(R.string.PREF_KEY_TWITTER_LOGIN));
e.commit();

// After this take the appropriate action
// I am showing the hiding/showing buttons again
// You might not needed this code
btnLogoutTwitter.setVisibility(View.GONE);
btnSearch.setVisibility(View.GONE);
searchET.setVisibility(View.GONE);
userNameTxt.setText("");

twitterList.setVisibility(View.GONE);

btnLoginTwitter.setVisibility(View.VISIBLE);
}

@Override
public void onClick(View v) {
switch (v.getId()) {

case R.id.btnLoginTwitter:
loginToTwitter();
break;
case R.id.btnSearch:
searchTweets();
break;
case R.id.btnLogoutTwitter:
logoutFromTwitter();

break;

default:
break;
}
}

}