<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>helw.net</title>
    <link>http://helw.net/index.xml</link>
    <description>Recent content on helw.net</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 31 Jan 2017 16:59:27 -0800</lastBuildDate>
    <atom:link href="http://helw.net/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>3 things i learned about rxjava 2 subjects</title>
      <link>http://helw.net/2017/01/31/3-things-i-learned-about-rxjava-2-subjects/</link>
      <pubDate>Tue, 31 Jan 2017 16:59:27 -0800</pubDate>
      
      <guid>http://helw.net/2017/01/31/3-things-i-learned-about-rxjava-2-subjects/</guid>
      <description>

&lt;h2 id=&#34;intro&#34;&gt;intro&lt;/h2&gt;

&lt;p&gt;sometime in late december or early january, i decided to write a blog post per month. since it’s january 31st, i figured i should write about something to avoid dropping the ball so early in the year.&lt;/p&gt;

&lt;p&gt;i introduced &lt;a href=&#34;http://www.2doapp.com/android/&#34;&gt;one of my friends&lt;/a&gt; to rxjava 2 not too long ago - his initial reaction was, &amp;ldquo;what? why would i want this?&amp;rdquo; - a few days later, it turned to, &amp;ldquo;hey, this is pretty cool!&amp;rdquo; - a few days after that, i learned several things from him as he ran into issues while migrating parts of his code.&lt;/p&gt;

&lt;p&gt;consequently, i wanted to share these things, as they weren&amp;rsquo;t perfectly obvious to me (though in retrospect, they perhaps should have been).&lt;/p&gt;

&lt;p&gt;also, i do realize that many consider subjects as “the mutable state of the reactive world” that should be avoided, but sometimes, they are a pretty good tool to use, especially when an entire code base is not yet reactive.&lt;/p&gt;

&lt;h2 id=&#34;retry-doesn-t-actually-retry&#34;&gt;retry doesn’t actually retry&lt;/h2&gt;

&lt;p&gt;consider this code:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;  @Test
  public void testRetry() {
    TestObserver&amp;lt;Integer&amp;gt; ts = new TestObserver&amp;lt;&amp;gt;();

    final boolean[] val = new boolean[] { true };
    Observable.just(1, 2, 3)
        .map(i -&amp;gt; {
          // fail only the first time that i = 2
          if (i == 2 &amp;amp;&amp;amp; val[0]) {
            val[0] = false;
            throw new IllegalArgumentException(&amp;quot;throw!&amp;quot;);
          }
          return i;
        })
        .retry()
        .subscribe(ts);

    ts.awaitTerminalEvent();
    assertThat(ts.values()).containsAllOf(1, 2, 3);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;this test passes, and the values emitted are &lt;code&gt;[1, 1, 2, 3]&lt;/code&gt;. i&amp;rsquo;ll come back to the repetition in a tiny bit. now consider if we make a small change to this code, so that it uses a subject instead:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;  @Test
  public void testRetrySubject() {
    TestObserver&amp;lt;Integer&amp;gt; ts = new TestObserver&amp;lt;&amp;gt;();
    Subject&amp;lt;Integer&amp;gt; subject = PublishSubject.create();

    final boolean[] val = new boolean[] { true };
    subject
        .map(i -&amp;gt; {
          if (i == 2 &amp;amp;&amp;amp; val[0]) {
            val[0] = false;
            throw new IllegalArgumentException(&amp;quot;throw!&amp;quot;);
          }
          return i;
        })
        .retry()
        .subscribe(ts);

    subject.onNext(1);
    subject.onNext(2);
    subject.onNext(3);
    subject.onComplete();

    ts.awaitTerminalEvent();
    assertThat(ts.values()).containsAllOf(1, 2, 3);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;this test now fails, outputting only &lt;code&gt;[1, 3]&lt;/code&gt;. so, why is this the case? the reason is that &lt;code&gt;retry&lt;/code&gt; doesn&amp;rsquo;t actually &lt;code&gt;retry&lt;/code&gt; anything - it just resubscribes to the source observable.&lt;/p&gt;

&lt;p&gt;so if we think of the flow in this case, we call &lt;code&gt;onNext&lt;/code&gt; with &lt;code&gt;1&lt;/code&gt;, which is observed by the subscriber. we then call it with &lt;code&gt;2&lt;/code&gt;, which fails because we throw an exception, and causes us to resubscribe. resubscribing to it doesn&amp;rsquo;t cause anything to emit. when &lt;code&gt;3&lt;/code&gt; is passed in, we then observe it.&lt;/p&gt;

&lt;p&gt;we can prove this by replacing the &lt;code&gt;PublishSubject&lt;/code&gt; with a &lt;code&gt;BehaviorSubject&lt;/code&gt; - doing so will result in &lt;code&gt;[1, 2, 3]&lt;/code&gt; (because the subject caches the last &lt;code&gt;onNext&lt;/code&gt; value it received, which was &lt;code&gt;2&lt;/code&gt;, so it gets replayed upon resubscribing).&lt;/p&gt;

&lt;p&gt;note that the fact that &lt;code&gt;retry&lt;/code&gt; resubscribes to the source observable is also why data can be repeated (as seen in the first example without subjects) - so when 2 fails the first time around, we re-subscribe, and thus get an &lt;code&gt;onNext&lt;/code&gt; of &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, and then &lt;code&gt;3&lt;/code&gt;, thus resulting in the repetition of the &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&#34;calling-subscribeon-on-a-subject-has-no-practical-effect&#34;&gt;calling subscribeOn on a subject has no practical effect&lt;/h2&gt;

&lt;p&gt;this one was strange to me at first, but made sense once i realized that the reasoning for this was the same as that of why only the subscribeOn closest to the source matters - in summary, it&amp;rsquo;s because once &lt;code&gt;onNext&lt;/code&gt; is called, downstream will receive the value on the same thread &lt;code&gt;onNext&lt;/code&gt; was called on.
thus, if you have &lt;code&gt;subject.subscribeOn(Schedulers.io())&lt;/code&gt;, but call &lt;code&gt;subject.onNext(value)&lt;/code&gt; from the main thread, the downstream will receive &lt;code&gt;onNext&lt;/code&gt; on the main thread.&lt;/p&gt;

&lt;p&gt;see also what i wrote &lt;a href=&#34;http://helw.net/2016/07/24/rxjava-and-a-synchronous-main-thread/&#34;&gt;here&lt;/a&gt; in the section about &amp;ldquo;only the subscribeOn closest to the source matters&amp;rdquo; (while that article was about rx1, it&amp;rsquo;s still relevant in rx2).&lt;/p&gt;

&lt;h2 id=&#34;observeon-s-buffer-and-rebatchrequests&#34;&gt;observeOn&amp;rsquo;s buffer and rebatchRequests&lt;/h2&gt;

&lt;p&gt;this comes from &lt;a href=&#34;http://stackoverflow.com/questions/41958423&#34;&gt;my friend&amp;rsquo;s question&lt;/a&gt; on stackoverflow. suppose we have a case where ui events trigger some work, but we only want to do that work if it&amp;rsquo;s not currently already being done - an example of this is a button that does work - and let&amp;rsquo;s suppose this takes a good amount of time, during which someone can click the button a few more times. if the work is being done, we don&amp;rsquo;t want to restart it, but if no work is being done, we can start doing the work.&lt;/p&gt;

&lt;p&gt;my friend realized, &amp;ldquo;aha, this sounds like something that backpressure can solve, let me use &lt;code&gt;BackpressureStrategy.LATEST&lt;/code&gt;!&amp;rdquo; - and so he implemented his solution to look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;  @Test
  public void testWork() {
    TestSubscriber&amp;lt;Integer&amp;gt; ts = new TestSubscriber&amp;lt;&amp;gt;();
    Subject&amp;lt;Integer&amp;gt; subject = PublishSubject.create();

    subject
        .toFlowable(BackpressureStrategy.LATEST)
        .observeOn(Schedulers.io())
        .map(ignored -&amp;gt; {
          System.err.println(&amp;quot;before work&amp;quot;);
          return ignored;
        })
        .observeOn(Schedulers.computation())
        .map(ignored -&amp;gt; {
          System.err.println(&amp;quot;work&amp;quot;);
          Thread.sleep(2000);
          return ignored;
        })
        .subscribe(ts);

    for (int i = 0; i &amp;lt; 32; i++) {
      subject.onNext(i);
    }
    subject.onComplete();

    ts.awaitTerminalEvent();
    assertThat(ts.valueCount()).isLessThan(32);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;this ended up failing, running the work 32 times - once for each and every emission of the subject. why?&lt;/p&gt;

&lt;p&gt;as i learned from &lt;a href=&#34;http://stackoverflow.com/questions/41958423&#34;&gt;David&amp;rsquo;s answer&lt;/a&gt;, this is because &lt;code&gt;observeOn&lt;/code&gt; has a buffer. since &lt;code&gt;BackpressureStrategy.LATEST&lt;/code&gt; only keeps the latest value &amp;ldquo;if the downstream can&amp;rsquo;t keep up,&amp;rdquo; and since the default buffer size is 128 (unless it is overwritten by a system preference, in which case it must at least be 16), all the &lt;code&gt;onNext&lt;/code&gt;s will be placed in a buffer until they can be sent downstream. in other words, backpressure doesn&amp;rsquo;t take effect here.&lt;/p&gt;

&lt;p&gt;one solution i came up with based on this was replacing the first &lt;code&gt;observeOn&lt;/code&gt; with &lt;code&gt;observeOn(Schedulers.io(), false, 1)&lt;/code&gt; - this &lt;code&gt;observeOn&lt;/code&gt; is called by the standard &lt;code&gt;observeOn&lt;/code&gt;, with &lt;code&gt;false&lt;/code&gt; for &lt;code&gt;delayError&lt;/code&gt;, and &lt;code&gt;bufferSize()&lt;/code&gt; for the buffer size. doing this results in the work only being done twice instead of 32 times. David said this would work, but would result in &amp;ldquo;time snapshots&amp;rdquo; as  opposed to the latest event being processed (because as the worker was being processed, item 2 would be in &lt;code&gt;observeOn&lt;/code&gt;&amp;rsquo;s queue, and would be sent downstream after the worker finishes - anything after 2 would be dropped until 2 is sent downstream).&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://stackoverflow.com/questions/41958423&#34;&gt;David&amp;rsquo;s solution&lt;/a&gt; that actually gives you the latest was interesting - first, he used &lt;code&gt;delay&lt;/code&gt; with 0ms as a means of switching threads without a buffer (i.e. &lt;code&gt;.delay(0, TimeUnit.MILLISECONDS, Schedulers.computation())&lt;/code&gt;). then, he calls &lt;code&gt;.rebatchRequests(1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rebatchRequests&lt;/code&gt; was added as an experimental operator in RxJava 1, and this was the first time i had seen it. from my understanding, this is like a valve of sorts - it requests &lt;code&gt;n&lt;/code&gt; items from upstream (based on the parameter passed in to it) - once 75% of them have been emitted downstream, it will request another &lt;code&gt;n&lt;/code&gt; items from upstream.&lt;/p&gt;

&lt;p&gt;it&amp;rsquo;s easier to understand what this is really doing when we look at how it&amp;rsquo;s implemented -&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;    public final Flowable&amp;lt;T&amp;gt; rebatchRequests(int n) {
        return observeOn(ImmediateThinScheduler.INSTANCE, true, n);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;hey, cool! it&amp;rsquo;s calling &lt;code&gt;observeOn&lt;/code&gt; with a buffer size of &lt;code&gt;n&lt;/code&gt;, which, in this case, is &lt;code&gt;1&lt;/code&gt;. &lt;code&gt;ImmediateThinScheduler&lt;/code&gt; is a scheduler that runs things immediately on the current thread.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>haramain updates</title>
      <link>http://helw.net/2016/11/13/haramain-updates/</link>
      <pubDate>Sun, 13 Nov 2016 23:06:18 -0800</pubDate>
      
      <guid>http://helw.net/2016/11/13/haramain-updates/</guid>
      <description>

&lt;p&gt;it&amp;rsquo;s been a while since i first wrote about &lt;a href=&#34;http://helw.net/2014/10/28/haramain-android&#34;&gt;Haramain&lt;/a&gt;. there have been some pretty massive updates recently that i wanted to briefly write about here.&lt;/p&gt;

&lt;h2 id=&#34;an-app-for-ios&#34;&gt;an app for iOS&lt;/h2&gt;

&lt;p&gt;i&amp;rsquo;ve wanted to release an app for iOS for a long time now, and unfortunately never got around to doing so. i thought Haramain was a good candidate to be a first app, and so august 29th of this year, i finally released &lt;a href=&#34;https://itunes.apple.com/us/app/haramain/id1120580567?mt=8&#34;&gt;Haramain for iOS&lt;/a&gt;, which is my first iOS app (i&amp;rsquo;ve played with iOS before on many occasions, but this is the first app that i wrote end to end).&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/haramain.iOS-11.14.2016.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/haramain.iOS-11.14.2016.png&#34;
 width=&#34;250&#34;  
 height=&#34;444&#34;  &gt;
&lt;/a&gt;&lt;a href=&#34;http://helw.net/images/haramain_audio.iOS-11.14.2016.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/haramain_audio.iOS-11.14.2016.png&#34;
 width=&#34;250&#34;  
 height=&#34;444&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the iOS app features a new design by &lt;a href=&#34;https://twitter.com/AhmadGalal&#34;&gt;Ahmed Galal&lt;/a&gt; and most of the features found on Android (except autoplay, which insha’Allah should come in the future).&lt;/p&gt;

&lt;h2 id=&#34;android-updates&#34;&gt;android updates&lt;/h2&gt;

&lt;p&gt;so the Android app also hasn’t seen updates for a while now, and with the iOS app out and with a new design, it was time to bring the new design to Android, with some modifications.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/haramain.android-11.14.2016.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/haramain.android-11.14.2016.png&#34;
 width=&#34;250&#34;  
 height=&#34;444&#34;  &gt;
&lt;/a&gt;&lt;a href=&#34;http://helw.net/images/haramain_audio.android-11.14.2016.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/haramain_audio.android-11.14.2016.png&#34;
 width=&#34;250&#34;  
 height=&#34;444&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;so today, i released an update to Haramain for Android. this new version features Ahmad’s new design. it also adds Chromecast support and support for Android 7.1 shortcuts.&lt;/p&gt;

&lt;h2 id=&#34;future-plans&#34;&gt;future plans&lt;/h2&gt;

&lt;p&gt;insha’Allah in the future, we have a few other things planned - namely search, Arabic support, and lists of favorites. stay tuned!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>rxjava and a synchronous main thread</title>
      <link>http://helw.net/2016/07/24/rxjava-and-a-synchronous-main-thread/</link>
      <pubDate>Sun, 24 Jul 2016 19:02:06 -0700</pubDate>
      
      <guid>http://helw.net/2016/07/24/rxjava-and-a-synchronous-main-thread/</guid>
      <description>

&lt;p&gt;not too long ago, someone pointed me to &lt;a href=&#34;http://blog.bradcampbell.nz/keep-your-main-thread-synchronous/&#34;&gt;this blog post&lt;/a&gt; about keeping your main thread synchronous. it referenced Ray Ryan&amp;rsquo;s excellent &lt;a href=&#34;https://www.youtube.com/watch?v=va1d4MqLUGY&#34;&gt;talk&lt;/a&gt; about the matter. the talk and blog post lead me to a set of investigations, which prompted me to write this blog post.&lt;/p&gt;

&lt;h4 id=&#34;quick-note-why-keep-the-main-thread-synchronous&#34;&gt;quick note: why keep the main thread synchronous&lt;/h4&gt;

&lt;p&gt;if you are curious as to the kinds of problems that can occur if the main thread isn&amp;rsquo;t synchronous (or why it&amp;rsquo;s not synchronous when you use &lt;code&gt;observeOn&lt;/code&gt;), see &lt;a href=&#34;https://corner.squareup.com/2013/12/android-main-thread-2.html&#34;&gt;this post&lt;/a&gt; about the main thread for a good explanation.&lt;/p&gt;

&lt;p&gt;the summary is that everytime you use &lt;code&gt;handler.post()&lt;/code&gt;, you post something to be run later, and you don&amp;rsquo;t have any guarantees as to &lt;em&gt;when&lt;/em&gt; it will be run. a common case is when you schedule something to update the ui, but before it actually runs, an &lt;code&gt;onDestroy&lt;/code&gt; comes in, causing the code to update the ui after the destruction of the activity.&lt;/p&gt;

&lt;p&gt;in rx, specifically, &lt;code&gt;observeOn(AndroidSchedulers.mainThread())&lt;/code&gt; causes a &lt;code&gt;handler.sendMessageDelayed&lt;/code&gt; (see &lt;a href=&#34;https://github.com/ReactiveX/RxAndroid/blob/master/rxandroid/src/main/java/rx/android/schedulers/LooperScheduler.java&#34;&gt;LooperScheduler.java&lt;/a&gt;), which could cause code to run at a point after we are thought to have unsubscribed, thus causing issues.&lt;/p&gt;

&lt;h4 id=&#34;basic-rules-of-rxjava-threading&#34;&gt;basic rules of rxjava threading&lt;/h4&gt;

&lt;p&gt;in &lt;a href=&#34;https://www.youtube.com/watch?v=QdmkXL7XikQ&#34;&gt;many&lt;/a&gt; of the &lt;a href=&#34;https://www.youtube.com/watch?v=NVKmyK6sd-Q&#34;&gt;talks&lt;/a&gt; about rxjava&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:video-footnote&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:video-footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, we find a set of repeated rules about rxjava and threading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rxjava is single threaded by default unless you explicitly ask it otherwise&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subscribeOn&lt;/code&gt; only affects upstream&lt;/li&gt;
&lt;li&gt;only the &lt;code&gt;subscribeOn&lt;/code&gt; closest to the source matters&lt;/li&gt;
&lt;li&gt;&lt;code&gt;observeOn&lt;/code&gt; only affects downstream&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;while these are all true, there are a few minor points that were not immediately obvious to me early on about the first three, so i would like to elaborate a bit on those.&lt;/p&gt;

&lt;h5 id=&#34;rxjava-is-single-threaded-by-default&#34;&gt;rxjava is single threaded by default&lt;/h5&gt;

&lt;p&gt;as long as you do not use &lt;code&gt;observeOn&lt;/code&gt;, &lt;code&gt;subscribeOn&lt;/code&gt;, or an operator that runs on a particular scheduler (ex &lt;code&gt;timer&lt;/code&gt;), the callback will be receieved on the thread &lt;code&gt;subscribe&lt;/code&gt; happened on.&lt;/p&gt;

&lt;h5 id=&#34;subscribeon-only-affects-upstream&#34;&gt;subscribeOn only affects upstream&lt;/h5&gt;

&lt;p&gt;one subtle point - consider:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;Observable.just(1, 2, 3)
    .subscribeOn(Schedulers.io())
    .subscribe(integer -&amp;gt; {
      Log.d(TAG, &amp;quot;got value on &amp;quot; + Thread.currentThread().getName());
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;despite &lt;code&gt;subscribeOn&lt;/code&gt; only affecting upstream, this will always print the result on an io thread, irrespective of the thread on which we called this code. this is because &lt;code&gt;subscribeOn&lt;/code&gt; subscribes to the observable on the thread passed in, which means that &lt;code&gt;onNext&lt;/code&gt; will be called on that particular thread.&lt;/p&gt;

&lt;h5 id=&#34;only-the-subscribeon-closest-to-the-source-matters&#34;&gt;only the subscribeOn closest to the source matters&lt;/h5&gt;

&lt;p&gt;consider this code:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;Observable.just(1, 2, 3)
    .doOnSubscribe(() -&amp;gt; 
        Log.d(TAG, &amp;quot;subscribe to just on &amp;quot; +
            Thread.currentThread().getName()))
    .subscribeOn(Schedulers.io())
    .filter(integer -&amp;gt; integer % 2 == 0)
    .doOnSubscribe(() -&amp;gt;
        Log.d(TAG, &amp;quot;subscribe to filter on &amp;quot; +
            Thread.currentThread().getName()))
    .subscribeOn(Schedulers.computation())
    .subscribe(integer -&amp;gt; {
      Log.d(TAG, &amp;quot;got value on &amp;quot; + Thread.currentThread().getName());
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;running this example results in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;D/are: subscribe to filter on RxComputationScheduler-1
D/are: subscribe to just on RxIoScheduler-2
D/are: got value on RxIoScheduler-2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;if, however, we changed &lt;code&gt;doOnSubscribe&lt;/code&gt; with &lt;code&gt;doOnNext&lt;/code&gt; in the code block above, we&amp;rsquo;d instead get:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;D/are: onNext from just with RxIoScheduler-2
D/are: onNext from just with RxIoScheduler-2
D/are: onNext from filter with RxIoScheduler-2
D/are: got value on RxIoScheduler-2
D/are: onNext from just with RxIoScheduler-2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;the caveat here is that the &lt;code&gt;subscribeOn&lt;/code&gt; closest to the source is the one that determines which thread &lt;code&gt;onNext&lt;/code&gt; will get called on (but subscriptions still happen on the thread specified by &lt;code&gt;subscribeOn&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;the reason for this is that each &lt;code&gt;subscribeOn&lt;/code&gt; subscribes to the upstream observable on that particular thread.&lt;/p&gt;

&lt;p&gt;let&amp;rsquo;s take an example - given:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;Observable.just(1,2,3)
          .subscribeOn(Schedulers.io())
          .subscribeOn(Schedulers.computation())
          .subscribe();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;let&amp;rsquo;s break down what happens:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;http://helw.net/images/subscribe_on-07.24.2016.png&#34; alt=&#34;diagram&#34; /&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Observable.just(1,2,3)&lt;/code&gt; internally calls &lt;code&gt;Observable.create(new OnSubscribeFromArray())&lt;/code&gt;, so we have an &lt;code&gt;Observable&lt;/code&gt; which will call &lt;code&gt;OnSubscribeFromArray&lt;/code&gt; on subscribe.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;we then call &lt;code&gt;subscribeOn(Schedulers.io())&lt;/code&gt;, which calls &lt;code&gt;Observable.create(new OperatorSubscribeOn(this, scheduler))&lt;/code&gt;, where &lt;code&gt;this&lt;/code&gt; is the &lt;code&gt;Observable&lt;/code&gt; from above, and &lt;code&gt;scheduler&lt;/code&gt; is &lt;code&gt;io&lt;/code&gt;. In other words, we now have an &lt;code&gt;Observable&lt;/code&gt;, which has an &lt;code&gt;onSubscribe&lt;/code&gt; that will &lt;code&gt;subscribe&lt;/code&gt; to the &lt;code&gt;Observable&lt;/code&gt; from the step above on the &lt;code&gt;io&lt;/code&gt; thread.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;we then call &lt;code&gt;subscribeOn(Schedulers.computation())&lt;/code&gt;, which calls &lt;code&gt;Observable.create(new OperatorSubscribeOn(this, scheduler))&lt;/code&gt;, where &lt;code&gt;this&lt;/code&gt; is the &lt;code&gt;Observable&lt;/code&gt; from above, and &lt;code&gt;scheduler&lt;/code&gt; is &lt;code&gt;computation&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;finally, we call &lt;code&gt;subscribe&lt;/code&gt;, which calls &lt;code&gt;Observable.subscribe&lt;/code&gt;, which calls the method from &lt;code&gt;OperatorSubscribeOn&lt;/code&gt; from point 3 - this &lt;code&gt;subscribe&lt;/code&gt;s to the &lt;code&gt;Observable&lt;/code&gt; from point 2 on the computation thread. Ultimately, this causes the &lt;code&gt;OperatorSubscribeOn&lt;/code&gt; from point 2 to be called, which then calls &lt;code&gt;subscribe&lt;/code&gt; to the &lt;code&gt;Observable&lt;/code&gt; from point 1 on the &lt;code&gt;io&lt;/code&gt; thread. &lt;code&gt;OnSubscribeFromArray&lt;/code&gt; produces values on the same thread, thus causing all the items to be emitted on the &lt;code&gt;io&lt;/code&gt; thread.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;see the &lt;a href=&#34;https://github.com/ReactiveX/RxJava/blob/1.x/src/main/java/rx/internal/operators/OperatorSubscribeOn.java&#34;&gt;source&lt;/a&gt; for &lt;code&gt;subscribeOn&lt;/code&gt; for more details.&lt;/p&gt;

&lt;h4 id=&#34;running-things-in-parallel-with-rxjava&#34;&gt;running things in parallel with rxjava&lt;/h4&gt;

&lt;p&gt;in order to run things in parallel, we use &lt;code&gt;flatMap&lt;/code&gt; or &lt;code&gt;concatMap&lt;/code&gt;, with multiple observers that can then &lt;code&gt;subscribeOn&lt;/code&gt; whatever scheduler they want to. the difference between &lt;code&gt;concatMap&lt;/code&gt; and &lt;code&gt;flatMap&lt;/code&gt; is that &lt;code&gt;flatMap&lt;/code&gt; can emit items out of order, whereas &lt;code&gt;concatMap&lt;/code&gt; will always emit items in order.&lt;/p&gt;

&lt;p&gt;so what does this do? &lt;code&gt;flatMap&lt;/code&gt; is essentially a &lt;code&gt;merge&lt;/code&gt;, which &amp;ldquo;combines multiple Observables into one by merging their emissions&amp;rdquo;&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:merge-footnote&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:merge-footnote&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. note that the &lt;a href=&#34;http://reactivex.io/documentation/contract.html&#34;&gt;observable contract&lt;/a&gt; stipulates that &amp;ldquo;Observables must issue notifications to observers serially (not in parallel).&amp;rdquo; this means that &lt;code&gt;onNext&lt;/code&gt; will not be called concurrently, and part of &lt;code&gt;merge&lt;/code&gt;&amp;rsquo;s job is to make sure that &lt;code&gt;onNext&lt;/code&gt; is only called by one thread at a time.&lt;/p&gt;

&lt;p&gt;for more on this, see &lt;a href=&#34;http://tomstechnicalblog.blogspot.com/2015/11/rxjava-achieving-parallelization.html&#34;&gt;Thomas Nield&amp;rsquo;s&lt;/a&gt; article about achieving parallelization, and also, see &lt;a href=&#34;http://akarnokd.blogspot.com/2016/02/flatmap-part-1.html&#34;&gt;David Karnok&amp;rsquo;s&lt;/a&gt; article about FlatMap.&lt;/p&gt;

&lt;p&gt;special thanks to &lt;a href=&#34;http://michaelevans.org&#34;&gt;Michael Evans&lt;/a&gt; for proofreading this.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr /&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:video-footnote&#34;&gt;both of the aforementioned talks are definitely worth watching if you haven&amp;rsquo;t already seen them!
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:video-footnote&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:merge-footnote&#34;&gt;quote from &lt;a href=&#34;http://reactivex.io/documentation/operators/merge.html&#34;&gt;rx merge docs&lt;/a&gt;
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:merge-footnote&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>rtl on Android</title>
      <link>http://helw.net/2016/05/01/rtl-on-android/</link>
      <pubDate>Sun, 01 May 2016 21:53:04 -0700</pubDate>
      
      <guid>http://helw.net/2016/05/01/rtl-on-android/</guid>
      <description>&lt;p&gt;i gave my first talk at &lt;a href=&#34;http://sf.droidcon.com&#34;&gt;droidcon sf&lt;/a&gt; this year.
the talk was about RTL on Android. check it out if you haven&amp;rsquo;t already (the
slides are &lt;a href=&#34;https://speakerdeck.com/ahmedre/from-right-to-left-and-back&#34;&gt;here&lt;/a&gt;).&lt;/p&gt;


&lt;div style=&#34;position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden;&#34;&gt;
  &lt;iframe src=&#34;//www.youtube.com/embed/4dJHtT4-vBE?&#34; 
  style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%;&#34; allowfullscreen frameborder=&#34;0&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>on LinearLayout measures</title>
      <link>http://helw.net/2016/01/27/on-linearlayout-measures/</link>
      <pubDate>Wed, 27 Jan 2016 22:34:30 -0800</pubDate>
      
      <guid>http://helw.net/2016/01/27/on-linearlayout-measures/</guid>
      <description>

&lt;p&gt;seeing that &lt;code&gt;LinearLayout&lt;/code&gt; is one of the most often used &lt;code&gt;ViewGroup&lt;/code&gt; types in Android development, i wanted to write a little bit about how &lt;code&gt;LinearLayout&lt;/code&gt; measures its children (this was also inspired by Sriram’s post about &lt;a href=&#34;https://sriramramani.wordpress.com/2015/05/06/custom-viewgroups&#34;&gt;Custom ViewGroups&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;tldr; (key takeaways that this post will discuss):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a (non-nested) &lt;code&gt;LinearLayout&lt;/code&gt; will measure each non-hidden child either 1x, 2x, or 3x (&lt;code&gt;gone&lt;/code&gt; views aren’t measured).&lt;/li&gt;
&lt;li&gt;whenever possible, set &lt;code&gt;android:baselineAligned&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;, especially when using weights.&lt;/li&gt;
&lt;li&gt;in a horizontal &lt;code&gt;LinearLayout&lt;/code&gt; with &lt;code&gt;wrap_content&lt;/code&gt; height, avoid setting any of the children’s heights to &lt;code&gt;match_parent&lt;/code&gt;. conversely, in a vertical &lt;code&gt;LinearLayout&lt;/code&gt; with &lt;code&gt;wrap_content&lt;/code&gt; width, avoid setting any of the children’s widths to &lt;code&gt;match_parent&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;linearlayout-and-child-measurement&#34;&gt;LinearLayout and child measurement&lt;/h2&gt;

&lt;p&gt;a (non-nested) &lt;code&gt;LinearLayout&lt;/code&gt; will end up measuring each non-hidden view either 1x, 2x, or 3x. here are the rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a View with &lt;code&gt;android:visibility=&amp;quot;gone&amp;quot;&lt;/code&gt; won’t be measured.&lt;/li&gt;
&lt;li&gt;a View will default to being measured once, unless more measurements are necessary (see rules 3 and 4).&lt;/li&gt;
&lt;li&gt;when the non-&lt;code&gt;android:orientation&lt;/code&gt; direction of the &lt;code&gt;LinearLayout&lt;/code&gt; is &lt;code&gt;wrap_content&lt;/code&gt; and its child’s is &lt;code&gt;match_parent&lt;/code&gt;,  the child will be measured an extra time.

&lt;ul&gt;
&lt;li&gt;in a horizontal &lt;code&gt;LinearLayout&lt;/code&gt; with &lt;code&gt;wrap_content&lt;/code&gt; height, a child with &lt;code&gt;match_parent&lt;/code&gt; height will be measured an extra time.&lt;/li&gt;
&lt;li&gt;in a vertical &lt;code&gt;LinearLayout&lt;/code&gt; with &lt;code&gt;wrap_content&lt;/code&gt; width, a child with &lt;code&gt;match_parent&lt;/code&gt; width will be measured an extra time.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;a child with a non-zero &lt;code&gt;android:layout_weight&lt;/code&gt; will be measured an extra time if:

&lt;ul&gt;
&lt;li&gt;in a horizontal &lt;code&gt;LinearLayout&lt;/code&gt; with non-&lt;code&gt;wrap_content&lt;/code&gt; width, &lt;code&gt;android:layout_width&lt;/code&gt; is not &lt;code&gt;0dp&lt;/code&gt;, (or is &lt;code&gt;0dp&lt;/code&gt;, but the &lt;code&gt;LinearLayout&lt;/code&gt; doesn’t have &lt;code&gt;android:baselineAligned=&amp;quot;false&amp;quot;&lt;/code&gt; set).&lt;/li&gt;
&lt;li&gt;in a vertical &lt;code&gt;LinearLayout&lt;/code&gt; with non-&lt;code&gt;wrap_content&lt;/code&gt; height, if &lt;code&gt;android:layout_height&lt;/code&gt; is not &lt;code&gt;0dp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;the first two rules are fairly straight forward - for optimization purposes, a view that is set to &lt;code&gt;gone&lt;/code&gt; will not be measured. secondly, every view must be measured at least once, so the default is that each view will be measured once, unless something causes it to have to measure more.&lt;/p&gt;

&lt;h3 id=&#34;the-width-height-mismatch-measure&#34;&gt;the width/height mismatch measure&lt;/h3&gt;

&lt;p&gt;consider a horizontal &lt;code&gt;LinearLayout&lt;/code&gt; with two &lt;code&gt;TextView&lt;/code&gt; children.&lt;/p&gt;

&lt;p&gt;if the height of this &lt;code&gt;LinearLayout&lt;/code&gt; is &lt;code&gt;match_parent&lt;/code&gt; or a fixed value (ex &lt;code&gt;32dp&lt;/code&gt;), then measuring the height of the children is easy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if the child has a fixed height, use that&lt;/li&gt;
&lt;li&gt;if the child’s height is &lt;code&gt;match_parent&lt;/code&gt;, then pass in the &lt;code&gt;LinearLayout&lt;/code&gt;’s height with a &lt;code&gt;MeasureSpec&lt;/code&gt; mode of &lt;code&gt;EXACTLY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;if the child’s height is &lt;code&gt;wrap_content&lt;/code&gt;, then pass in the &lt;code&gt;LinearLayout&lt;/code&gt;’s height with a &lt;code&gt;MeasureSpec&lt;/code&gt; mode of &lt;code&gt;AT_MOST&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;but what if the &lt;code&gt;LinearLayout&lt;/code&gt;’s height is &lt;code&gt;wrap_content&lt;/code&gt;? in this case, measuring the child is sometimes easy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if the child has a fixed height, use that.&lt;/li&gt;
&lt;li&gt;if the child has a height of &lt;code&gt;wrap_content&lt;/code&gt;, pass a height &lt;code&gt;MeasureSpec&lt;/code&gt; with a mode of &lt;code&gt;AT_MOST&lt;/code&gt; and the available space to the &lt;code&gt;LinearLayout&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;if, however, the child has a height of &lt;code&gt;match_parent&lt;/code&gt;, what we’re really saying is, “i want this view to have the same height as the &lt;code&gt;LinearLayout&lt;/code&gt;.”&lt;/p&gt;

&lt;p&gt;so what is the height of the &lt;code&gt;LinearLayout&lt;/code&gt;? in the case where the &lt;code&gt;LinearLayout&lt;/code&gt;’s height is set to &lt;code&gt;wrap_content&lt;/code&gt;, the height is not known until each child has been measured (the height &lt;code&gt;MeasureSpec&lt;/code&gt; received in &lt;code&gt;onMeasure&lt;/code&gt; by the &lt;code&gt;LinearLayout&lt;/code&gt; itself will be &lt;code&gt;AT_MOST&lt;/code&gt; with however much space can be taken up by it).&lt;/p&gt;

&lt;p&gt;consequently, children with a &lt;code&gt;match_parent&lt;/code&gt; height also have to wait until the &lt;code&gt;LinearLayout&lt;/code&gt;’s height is determined, and then measured again in accordance to that height.&lt;/p&gt;

&lt;p&gt;note that the same is true for vertical &lt;code&gt;LinearLayout&lt;/code&gt;s when they have &lt;code&gt;wrap_content&lt;/code&gt; widths and children with &lt;code&gt;match_parent&lt;/code&gt; widths.&lt;/p&gt;

&lt;p&gt;(note that in &lt;a href=&#34;https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/widget/LinearLayout.java&#34; title=&#34;LinearLayout.java&#34;&gt;LinearLayout.java&lt;/a&gt;, you’ll see &lt;code&gt;forceUniformHeight&lt;/code&gt; and &lt;code&gt;forceUniformWidth&lt;/code&gt; in &lt;code&gt;measureHorizontal&lt;/code&gt; and &lt;code&gt;measureVertical&lt;/code&gt;, respectively, being called at the end of the measure cycle when they need to be).&lt;/p&gt;

&lt;h4 id=&#34;example&#34;&gt;example&lt;/h4&gt;

&lt;p&gt;here’s an example that shows this effect - compare:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/ll_height_mismatch-01.27.2016&#34;&gt;&lt;img src=&#34;http://helw.net/images/ll_height_mismatch-01.27.2016.png&#34;
 width=&#34;240&#34;  
 height=&#34;426&#34;  &gt;
&lt;/a&gt;&lt;a href=&#34;http://helw.net/images/ll_height_mismatch-01.27.2016&#34;&gt;&lt;img src=&#34;http://helw.net/images/ll_height_no_mismatch-01.27.2016.png&#34;
 width=&#34;240&#34;  
 height=&#34;426&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the right square in the first image is measured twice, because its
height is set to &lt;code&gt;match_parent&lt;/code&gt; when the &lt;code&gt;LinearLayout&lt;/code&gt;&amp;rsquo;s height is set to
&lt;code&gt;wrap_content&lt;/code&gt;. if these match (ex both are &lt;code&gt;wrap_content&lt;/code&gt;, both are
&lt;code&gt;match_parent&lt;/code&gt;, or one of them is fixed), we eliminate this
problem&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:nested-mismatch-footnote&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:nested-mismatch-footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;note that sometimes, you really have to use &lt;code&gt;match_parent&lt;/code&gt; - for example, if
the right side had a background and we wanted it to be exactly the same
height as the left side, we have no choice but to use &lt;code&gt;match_parent&lt;/code&gt; for the
height (unless we can specify a fixed height or change the parent, etc).&lt;/p&gt;

&lt;h3 id=&#34;weights&#34;&gt;weights&lt;/h3&gt;

&lt;p&gt;setting a non-zero &lt;code&gt;android:layout_weight&lt;/code&gt; may cause a View to be measured an extra time.&lt;/p&gt;

&lt;p&gt;first, let’s consider when a non-zero &lt;code&gt;android:layout_weight&lt;/code&gt; does &lt;em&gt;not&lt;/em&gt; cause an extra measure pass -&lt;/p&gt;

&lt;p&gt;for a vertical &lt;code&gt;LinearLayout&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when the &lt;code&gt;LinearLayout&lt;/code&gt; has a &lt;code&gt;layout_height&lt;/code&gt; of &lt;code&gt;wrap_content&lt;/code&gt;, there is no extra measure (this makes sense, since there is no “extra space” to divvy up amongst the views at the end, since we’re telling the &lt;code&gt;LinearLayout&lt;/code&gt; to only be as large as its content).&lt;/li&gt;
&lt;li&gt;when the &lt;code&gt;layout_height&lt;/code&gt; of the child is &lt;code&gt;0dp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for a horizontal &lt;code&gt;LinearLayout&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when the &lt;code&gt;LinearLayout&lt;/code&gt; has a &lt;code&gt;layout_width&lt;/code&gt; of &lt;code&gt;wrap_content&lt;/code&gt;, there is no extra measure.&lt;/li&gt;
&lt;li&gt;when the &lt;code&gt;layout_width&lt;/code&gt; of the child is &lt;code&gt;0dp&lt;/code&gt;, and the &lt;code&gt;LinearLayout&lt;/code&gt; itself has &lt;code&gt;android:baselineAligned=&amp;quot;false&amp;quot;&lt;/code&gt; set.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in all other cases, the view with non-zero &lt;code&gt;layout_weight&lt;/code&gt; will be measured an extra time.&lt;/p&gt;

&lt;h4 id=&#34;android-baselinealigned&#34;&gt;android:baselineAligned&lt;/h4&gt;

&lt;p&gt;the documentation for &lt;a href=&#34;http://developer.android.com/reference/android/widget/LinearLayout.html#attr_android:baselineAligned&#34; title=&#34;android:baselineAligned&#34;&gt;android:baselineAligned&lt;/a&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When set to false, prevents the layout from aligning its children&amp;rsquo;s baselines. This attribute is particularly useful when the children use different values for gravity. The default value is true.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;this is generally useful for aligning text with the same gravity. consider:&lt;/p&gt;

&lt;img src=&#34;http://helw.net/images/baseline_aligned-01.27.2016.png&#34;
 width=&#34;240&#34;  
 height=&#34;51&#34;  &gt;


&lt;p&gt;and compare it to:&lt;/p&gt;

&lt;img src=&#34;http://helw.net/images/baseline_not_aligned-01.27.2016.png&#34;
 width=&#34;287&#34;  
 height=&#34;49&#34;  &gt;


&lt;p&gt;here&amp;rsquo;s a more visual representation:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/ll_weight_aligned-01.27.2016.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/ll_weight_aligned-01.27.2016.png&#34;
 width=&#34;240&#34;  
 height=&#34;426&#34;  &gt;
&lt;/a&gt;&lt;a href=&#34;http://helw.net/images/ll_weight_not_aligned-01.27.2016.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/ll_weight_not_aligned-01.27.2016.png&#34;
 width=&#34;240&#34;  
 height=&#34;426&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;so when can you turn it off?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;if the children of the &lt;code&gt;LinearLayout&lt;/code&gt; don’t need to be baseline aligned (i.e. are not &lt;code&gt;TextView&lt;/code&gt;s or &lt;code&gt;ImageView&lt;/code&gt;s with &lt;a href=&#34;http://developer.android.com/reference/android/widget/ImageView.html#setBaseline(int)&#34; title=&#34;ImageView: setBaseline&#34;&gt;setBaseline&lt;/a&gt; or &lt;code&gt;setBaselineAlignedBottom&lt;/code&gt; set, etc).&lt;/li&gt;
&lt;li&gt;if the children are &lt;code&gt;TextView&lt;/code&gt;s but all have different alignments anyway.&lt;/li&gt;
&lt;li&gt;if it doesn&amp;rsquo;t matter (for example in the above screenshots, because both sides use English text with the same text size, the images are identical - if they were different languages, or if the text size of one was different than the other, the two would definitely be different).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;here&amp;rsquo;s a visual representation of how &lt;code&gt;baselineAlignment&lt;/code&gt; can make a difference:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/ll_weight_aligned_different-01.27.2016.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/ll_weight_aligned_different-01.27.2016.png&#34;
 width=&#34;240&#34;  
 height=&#34;426&#34;  &gt;
&lt;/a&gt;&lt;a href=&#34;http://helw.net/images/ll_weight_not_aligned_different-01.27.2016.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/ll_weight_not_aligned_different-01.27.2016.png&#34;
 width=&#34;240&#34;  
 height=&#34;426&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;why-does-this-matter&#34;&gt;why does this matter?&lt;/h2&gt;

&lt;p&gt;why write a blog post about this, and why does it matter? there are 2 main reasons - first, given the popularity of &lt;code&gt;LinearLayout&lt;/code&gt; within most apps, its important to know how it works to have great performing apps.&lt;/p&gt;

&lt;p&gt;secondly, measures can be expensive - and avoiding extra work is always great! this is especially relevant when you consider nested &lt;code&gt;LinearLayout&lt;/code&gt;s - let’s suppose that a nested &lt;code&gt;LinearLayout&lt;/code&gt; will be measured 3 times, and has children that it would ordinarily measure 3x - those children now get measured 7&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:nested-measures-footnote&#34;&gt;&lt;a rel=&#34;footnote&#34; href=&#34;#fn:nested-measures-footnote&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; times!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr /&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:nested-mismatch-footnote&#34;&gt;note that this is only true for a non-nested LinearLayout - if instead, the aforementioned layout is the child of a vertical LinearLayout with a height of wrap_content, the TextView with match_parent height will still get measured twice, because the extra measure at the end happens when a child is match_parent and the parent&amp;rsquo;s height MeasureSpec is not EXACTLY (in this case, its AT_MOST due to wrap_content).
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:nested-mismatch-footnote&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:nested-measures-footnote&#34;&gt;in theory, they’d get measured 9 times, but the variation in the specs that are passed in to the nested LinearLayout let some of the views skip extra measures, especially in the first 2 measure passes.
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:nested-measures-footnote&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>intellij structural replace</title>
      <link>http://helw.net/2015/12/09/intellij-structural-replace/</link>
      <pubDate>Wed, 09 Dec 2015 23:48:30 -0800</pubDate>
      
      <guid>http://helw.net/2015/12/09/intellij-structural-replace/</guid>
      <description>&lt;p&gt;intellij&amp;rsquo;s &lt;a href=&#34;https://www.jetbrains.com/idea/help/structural-search-and-replace.html&#34;&gt;structural search and replace&lt;/a&gt; is an amazing feature that can save a lot of time. the value of this feature first hit home in the excellent &lt;a href=&#34;https://www.youtube.com/watch?v=Y2GC6P5hPeA&#34;&gt;Android Studio for Experts&lt;/a&gt; talk during Android Dev Summit 2015 (excellent video if you haven&amp;rsquo;t already seen it, btw!)&lt;/p&gt;

&lt;p&gt;today, i was trying to replace my usages of &lt;code&gt;android.util.Log.*&lt;/code&gt; with &lt;a href=&#34;https://github.com/JakeWharton/timber&#34;&gt;Timber&lt;/a&gt;. to use Timber, we&amp;rsquo;d need to manually replace &lt;code&gt;Log.d(TAG, &amp;quot;message&amp;quot;);&lt;/code&gt; with &lt;code&gt;Timber.d(&amp;quot;message&amp;quot;);&lt;/code&gt;, and the same for &lt;code&gt;Log.e&lt;/code&gt;, &lt;code&gt;Log.w&lt;/code&gt;, and so on. there&amp;rsquo;s also a version of &lt;code&gt;Log.*&lt;/code&gt; that takes in an exception as a paramter that we have to keep in mind as well.&lt;/p&gt;

&lt;p&gt;sounds like a perfect job for structural search - we bring it up by using &lt;code&gt;⌘ + shift + A&lt;/code&gt; to search for actions. type &lt;code&gt;Structurally&lt;/code&gt;, and choose &lt;code&gt;Replace Structurally&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;we&amp;rsquo;ll get a dialog that we&amp;rsquo;ll fill out like this:
&lt;a href=&#34;http://helw.net/images/structural.replace-12.09.2015.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/structural.replace-12.09.2015.png&#34;
 
 &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;so to do this, set the search template to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;android.util.Log.$something$($tag$, $params$);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;set the replacement template to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;timber.log.Timber.$something$($params$);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;note that the fully qualified domain name in the replacement ensures that the import is handled for you, as long as &lt;em&gt;shorten fully qualified names&lt;/em&gt; is checked.&lt;/p&gt;

&lt;p&gt;finally, choose &lt;code&gt;Edit variables&lt;/code&gt;, choose &lt;code&gt;params&lt;/code&gt; on the left, and click the &lt;code&gt;unlimited&lt;/code&gt; box by maximum count. this is so that we match both &lt;code&gt;Log.d(TAG, &amp;quot;message&amp;quot;);&lt;/code&gt; and &lt;code&gt;Log.d(TAG, &amp;quot;message&amp;quot;, exception);&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;some notes about the options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;shorten fully qualified names&lt;/em&gt; replaces things like &lt;code&gt;android.util.Log.d&lt;/code&gt; with &lt;code&gt;Log.d&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;reformat according to style&lt;/em&gt; will fix the indentation if it&amp;rsquo;s wrong.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;use static import if possible&lt;/em&gt; will prefer &lt;code&gt;import static&lt;/code&gt; - i&amp;rsquo;ve unchecked this because i&amp;rsquo;ve found that it did this for many things that i didn&amp;rsquo;t want it done for.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and there you have it. as always, source control is your friend, so make sure to do this on a branch where you can validate the changes and easily roll back if things aren&amp;rsquo;t quite right.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>quran android no longer open source</title>
      <link>http://helw.net/2015/08/09/quran-android-no-longer-open-source/</link>
      <pubDate>Sun, 09 Aug 2015 17:02:37 -0700</pubDate>
      
      <guid>http://helw.net/2015/08/09/quran-android-no-longer-open-source/</guid>
      <description>&lt;p&gt;&lt;em&gt;update&lt;/em&gt; - as of 12/31/2015, i&amp;rsquo;ve re-open sourced the app after the discussion
&lt;a href=&#34;https://github.com/quran/quran_android/issues/591&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;today is a very sad day for me, since i have finally decided to close quran android&amp;rsquo;s source code once and for all. throughout the past few years, i&amp;rsquo;ve come across several examples of people republishing the app with the intention of making money (placing ads on the index page, or, worse yet, on the top and bottom of each quran page while reading). recently, someone brought to my attention an example of someone repackaging the apk and shipping it with malware.&lt;/p&gt;

&lt;p&gt;for example, &lt;a href=&#34;http://fabric.io&#34;&gt;fabric&lt;/a&gt; shows me this crash:
&lt;a href=&#34;http://helw.net/images/referrer.track-08.09.2015.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/referrer.track-08.09.2015.png&#34;
 
 &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;this issue is happening on the current version in the play store, which was pushed on 5/31/2015. looking at the graph, you can see that until mid July, there were no crashes (because this sdk doesn&amp;rsquo;t exist in our app). after mid-July, someone pushed this (modified) apk somewhere, people started downloading it, and it started reporting crashes to me.&lt;/p&gt;

&lt;p&gt;a similar thing happened some time back, but with the person pushing their own version:
&lt;a href=&#34;http://helw.net/images/inmobi-08.09.2015.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/inmobi-08.09.2015.png&#34;
 
 &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;a few years ago, i closed the source to quran android for similar reasons, only to end up bringing it back after a few months, figuring the benefit of it being open outweighs the harm. unfortunately, this time, the decision is not meant to be reversed insha&amp;rsquo;Allah.&lt;/p&gt;

&lt;p&gt;i&amp;rsquo;ve come to the difficult realization that apps are not meant to be open sourced, because, when you open source it, there will always be people who try to profit off of your work (or destroy its credibility, etc).&lt;/p&gt;

&lt;p&gt;quran will, insha&amp;rsquo;Allah, continue to be developed, but it won&amp;rsquo;t be open source anymore. the existing github project will be used to track issues. while i understand that removing the code will not completely stop these things from happening (apks are very easy to reverse engineer, and people with a will to do something will find a way), at the very least, i can stop making it super easy for people.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;update&lt;/em&gt; - this seems to be a &lt;a href=&#34;http://stackoverflow.com/questions/32080414/what-is-com-walkfreestub-causing-crashes-on-android&#34;&gt;trojan&lt;/a&gt; that affects multiple apps downloaded from unofficial app stores.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>migrating to hugo from hexo</title>
      <link>http://helw.net/2015/07/19/migrating-to-hugo-from-hexo/</link>
      <pubDate>Sun, 19 Jul 2015 15:56:53 -0700</pubDate>
      
      <guid>http://helw.net/2015/07/19/migrating-to-hugo-from-hexo/</guid>
      <description>

&lt;p&gt;i haven&amp;rsquo;t written in a long time. it&amp;rsquo;s not that i have nothing to write about
(i actually have a set of post ideas written somewhere), but more of just not
having the time for writing.&lt;/p&gt;

&lt;p&gt;just yesterday, after seeing a fellow developer&amp;rsquo;s new blog based on jekyll, i
decided to search for a nicer theme for this blog. in the process, i came
across &lt;a href=&#34;http://gohugo.io/&#34;&gt;hugo&lt;/a&gt;, a blogging engine written using go. the two
things that interested me the most about it was the fact that it was supposed
to be super fast (whereas regenerating files for hexo still took a bit of
time), that it was written in go (which i hope to learn one day), and that i
found a theme i liked for it. the fact that chrome on the latest el capitan
beta doesn&amp;rsquo;t load my site at all was yet another reason to push me to go for
it.&lt;/p&gt;

&lt;p&gt;the process didn&amp;rsquo;t end up being too bad, and i&amp;rsquo;ll document some interesting
tidbits i found here in case someone else goes through the migration in the
future.&lt;/p&gt;

&lt;h3 id=&#34;fixing-the-metadata&#34;&gt;fixing the metadata.&lt;/h3&gt;

&lt;p&gt;there are a few important pieces required to fix the metadata - first, ensuring all lines start with &lt;code&gt;---&lt;/code&gt;. for me, any files i generated on &lt;a href=&#34;http://hexo.io&#34;&gt;hexo&lt;/a&gt; didn&amp;rsquo;t have &lt;code&gt;---&lt;/code&gt; on the top of them. secondly, fixing the dates. hexo dates were in a different format than the iso8601 format dates. furthermore, some of the entries i had wrapped their dates with single quotes.&lt;/p&gt;

&lt;p&gt;i found something &lt;a href=&#34;http://discuss.gohugo.io/t/more-flexible-frontmater-parser/393/3&#34;&gt;here&lt;/a&gt; to do this, and modified it to fix the single quote issue as well:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# ensure dates don&#39;t start with single quotes
for file in *; do awk &#39;{
if ($1 == &amp;quot;date:&amp;quot;) {
  gsub(&amp;quot;\047&amp;quot;, &amp;quot;&amp;quot;, $0); print;
} else {
  print $0;
}
}&#39; &amp;quot;$file&amp;quot; &amp;gt; temp.md &amp;amp;&amp;amp; mv temp.md $file ; done

# fix the dates and add the three dashes as the first line
for file in *; do awk &#39;{
  if (NR == 1) { print &amp;quot;---&amp;quot;; }
  if ($1 == &amp;quot;date:&amp;quot;) {
    printf(&amp;quot;%s %sT%s-05:00\n&amp;quot;, $1, $2, $3);
  } else {
    print $0;
  }
}&#39; &amp;quot;$file&amp;quot; &amp;gt; temp.md &amp;amp;&amp;amp; mv temp.md $file ; done

# wrap dates with quotes that aren&#39;t wrapped in quotes
for file in *; do awk &#39;{
  if ($1 == &amp;quot;date:&amp;quot;) {
    if ($2 ~ /^&amp;quot;/) {
      print $0;
    } else {
      printf(&amp;quot;%s \&amp;quot;%s\&amp;quot;\n&amp;quot;, $1, $2);
    }
  } else { print $0; }
}&#39; &amp;quot;$file&amp;quot; &amp;gt; temp.md &amp;amp;&amp;amp; mv temp.md $file; done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;one last thing was that some of the entries i had were missing the seconds field, and hugo complained about being unable to parse their times. since they were only a handfull of entries, i went ahead and fixed them manually.&lt;/p&gt;

&lt;h3 id=&#34;fixing-code-highlighting&#34;&gt;fixing code highlighting&lt;/h3&gt;

&lt;p&gt;i used something like this to convert the &lt;code&gt;codeblock&lt;/code&gt; style to the pygments driven code highlighting:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;for file in *.md; do awk &#39;{
if ($2 == &amp;quot;codeblock&amp;quot;) { gsub(&amp;quot;lang:&amp;quot;, &amp;quot;&amp;quot;, $(NF-1));
  printf(&amp;quot;%s&amp;lt; highlight %s &amp;gt;}}\n&amp;quot;, &amp;quot;{{&amp;quot;, $(NF-1));
} else if ($2 == &amp;quot;endcodeblock&amp;quot;) {
  printf(&amp;quot;%s&amp;lt; /highlight &amp;gt;}}\n&amp;quot;, &amp;quot;{{&amp;quot;);
} else { print $0; }
}&#39; &amp;quot;$file&amp;quot; &amp;gt; temp.md &amp;amp;&amp;amp; mv temp.md $file ; done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;as a recommendation, if trying to use the &lt;a href=&#34;https://github.com/spf13/hyde&#34;&gt;hyde&lt;/a&gt; theme, set &lt;code&gt;pygmentsUseClasses&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; in the configuration file.&lt;/p&gt;

&lt;p&gt;after doing this, i realized that i wanted to use &lt;a href=&#34;https://github.com/zyro/hyde-x&#34;&gt;hyde-x&lt;/a&gt;, which by default uses &lt;a href=&#34;http://highlightjs.org/&#34;&gt;highlight.js&lt;/a&gt;. i made this work (after running the above) by running:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;find . -exec sed -i &#39;.bak&#39; &#39;s/{{&amp;lt; highlight \(.*\) &amp;gt;}}/```\1/&#39; {} \;
find . -exec sed -i &#39;.bak&#39; &#39;s/{{&amp;lt; \/highlight &amp;gt;}}/```/&#39; {} \;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;fixing-images&#34;&gt;fixing images&lt;/h3&gt;

&lt;p&gt;hugo supports &lt;a href=&#34;http://gohugo.io/extras/shortcodes/&#34;&gt;shortcodes&lt;/a&gt; as a means for extending markdown. using a combination of the &lt;a href=&#34;http://gohugo.io/tutorials/migrate-from-jekyll/&#34;&gt;migrate to hugo from jekyll&lt;/a&gt; article, the &lt;a href=&#34;http://gohugo.io/extras/shortcodes/&#34;&gt;shortcodes&lt;/a&gt; documentation, and &lt;a href=&#34;nathanleclaire.com/blog/2014/12/22/migrating-to-hugo-from-octopress/&#34;&gt;migrating to hugo from octopress&lt;/a&gt;, i came up with a similar approach for fixing images that had a width and height in them.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;find . -exec sed -i &#39;.bak&#39; &#39;s/{% img \([^ ]*\) \([^ ]*\) \([^ ]*\) %}/{{&amp;lt; img src=&amp;quot;\1&amp;quot; width=&amp;quot;\2&amp;quot; height=&amp;quot;\3&amp;quot; &amp;gt;}}/&#39; {} \;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;this was combined with adding an img shortcode, which looked like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-html&#34;&gt;&amp;lt;img src=&amp;quot;{{ .Get &amp;quot;src&amp;quot; }}&amp;quot;
{{ if .Get &amp;quot;width&amp;quot; }} width=&amp;quot;{{.Get &amp;quot;width&amp;quot; }}&amp;quot; {{ end }}
{{ if .Get &amp;quot;height&amp;quot; }} height=&amp;quot;{{.Get &amp;quot;height&amp;quot; }}&amp;quot; {{ end }} &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;in addition, i modified the css to remove &lt;code&gt;display:block&lt;/code&gt; from &lt;code&gt;poole.css&lt;/code&gt; under &lt;code&gt;images&lt;/code&gt; to allow having two images side by side.&lt;/p&gt;

&lt;p&gt;one other minor thing i found was that &lt;code&gt;layout: post&lt;/code&gt;, which was either an artifact of hexo or octopress, was breaking disqus rendering. i fixed this by doing this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;for file in *.md; do
   grep -v &amp;quot;layout: post&amp;quot; $file &amp;gt; temp.md
   mv temp.md $file
done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;a little bit of extra tweaking to the settings and layouts and i was good to go! hopefully, this will push me to write posts a little bit more frequently :)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>mouse scrolling with RecyclerView</title>
      <link>http://helw.net/2014/12/29/mouse-scrolling-with-recyclerview/</link>
      <pubDate>Mon, 29 Dec 2014 21:11:50 -0700</pubDate>
      
      <guid>http://helw.net/2014/12/29/mouse-scrolling-with-recyclerview/</guid>
      <description>&lt;p&gt;i&amp;rsquo;ve recently began using &lt;a href=&#34;https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html&#34;&gt;RecyclerView&lt;/a&gt; in some of my projects, and one thing that stood out as being broken was that mouse scrolling no longer worked. while this is perhaps only a theoretical issue, it is fairly vexing when developing on an emulator, especially while dealing with long lists of data. i&amp;rsquo;ve opened a &lt;a href=&#34;https://code.google.com/p/android/issues/detail?id=91469&#34;&gt;bug&lt;/a&gt; about it.&lt;/p&gt;

&lt;p&gt;this is solved by using &lt;a href=&#34;http://developer.android.com/reference/android/view/View.html#onGenericMotionEvent(android.view.MotionEvent)&#34;&gt;onGenericMotionEvent&lt;/a&gt;. as per the documentation, &amp;ldquo;Generic motion events describe joystick movements, mouse hovers, track pad touches, scroll wheel movements and other input events.&amp;rdquo; for our RecyclerView, we basically have two options - one is to use &lt;a href=&#34;http://developer.android.com/reference/android/view/View.html#setOnGenericMotionListener(android.view.View.OnGenericMotionListener)&#34;&gt;setOnGenericMotionListener&lt;/a&gt;, and the other is to have our own subclass of RecyclerView to handle this.&lt;/p&gt;

&lt;p&gt;below, you will see the subclass solution (which can be easily adopted for use with &lt;code&gt;setOnGenericMotionListener&lt;/code&gt; as well). the code here is adopted from &lt;code&gt;AbsListView&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;public class CustomRecyclerView extends RecyclerView {
  private Context mContext;
  private float mVerticalScrollFactor;

  // constructors omitted for brevity

  private float getVerticalScrollFactor() {
    if (mVerticalScrollFactor == 0) {
      TypedValue outValue = new TypedValue();
      if (!mContext.getTheme().resolveAttribute(
          R.attr.listPreferredItemHeight, outValue, true)) {
        throw new IllegalStateException(
            &amp;quot;Expected theme to define listPreferredItemHeight.&amp;quot;);
      }
      mVerticalScrollFactor = outValue.getDimension(
          mContext.getResources().getDisplayMetrics());
    }
    return mVerticalScrollFactor;
  }

  @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
  @Override
  public boolean onGenericMotionEvent(MotionEvent event) {
    if ((event.getSource() &amp;amp; InputDevice.SOURCE_CLASS_POINTER) != 0) {
      if (event.getAction() == MotionEvent.ACTION_SCROLL &amp;amp;&amp;amp;
          getScrollState() == SCROLL_STATE_IDLE) {
        final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
        if (vscroll != 0) {
          final int delta = -1 * (int) (vscroll * getVerticalScrollFactor());
          if (ViewCompat.canScrollVertically(this, delta &amp;gt; 0 ? 1 : -1)) {
            scrollBy(0, delta);
            return true;
          }
        }
      }
    }
    return super.onGenericMotionEvent(event);
  }
}
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    
    <item>
      <title>haramain for android</title>
      <link>http://helw.net/2014/10/28/haramain-for-android/</link>
      <pubDate>Tue, 28 Oct 2014 00:19:55 -0700</pubDate>
      
      <guid>http://helw.net/2014/10/28/haramain-for-android/</guid>
      <description>&lt;p&gt;one of my favorite sites on the web is &lt;a href=&#34;http://haramain.info&#34;&gt;haramain recordings&lt;/a&gt;. haramain recordings posts the latest prayers from masjid al haram and masjid al nabawi on a daily basis (every fajr, maghrib, and isha salah, along with jum3a khutbas, salat al tarawee7, and more).&lt;/p&gt;

&lt;p&gt;because i found myself visiting haramain recordings very frequently, i started thinking, &amp;ldquo;it would be really great if i could access this on my phone&amp;hellip;&amp;rdquo; and so, al7amdulillah, haramain for android was built.&lt;/p&gt;

&lt;p&gt;haramain is an unofficial client for haramain recordings. it lets you stream the latest prayers from both masajid, and even lets you filter by sheikh. it was designed in accordance to material design, so it should look great on android L insha&amp;rsquo;Allah. it&amp;rsquo;s also free with no ads.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/haramain.makkah.10.28.2014.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/haramain.makkah.10.28.2014.png&#34;
 width=&#34;270&#34;  
 height=&#34;480&#34;  &gt;
&lt;/a&gt; &lt;a href=&#34;http://helw.net/images/haramain.juhany.10.28.2014.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/haramain.juhany.10.28.2014.png&#34;
 width=&#34;270&#34;  
 height=&#34;480&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;it&amp;rsquo;s quite light weight at the moment, and there are a lot of things that are missing, but insha&amp;rsquo;Allah as time goes on, we hope to keep updating it and make it more useful to people.&lt;/p&gt;

&lt;p&gt;the app&amp;rsquo;s account is on Twitter at &lt;a href=&#34;http://twitter.com/haramainapp&#34;&gt;@haramainapp&lt;/a&gt;, and you can download it from &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.quranicaudio.haramain&#34;&gt;google play&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>ripples with probe</title>
      <link>http://helw.net/2014/10/13/ripples-with-probe/</link>
      <pubDate>Mon, 13 Oct 2014 23:19:57 -0700</pubDate>
      
      <guid>http://helw.net/2014/10/13/ripples-with-probe/</guid>
      <description>&lt;p&gt;today, i was having a discussion with &lt;a href=&#34;https://github.com/mostafagazar&#34;&gt;Mostafa Gazar&lt;/a&gt; about android animations and his &lt;a href=&#34;https://github.com/MostafaGazar/Widgets&#34;&gt;Widgets&lt;/a&gt; library, and &lt;a href=&#34;http://lucasr.org/&#34;&gt;Lucas Rocha&amp;rsquo;s&lt;/a&gt; &lt;a href=&#34;https://github.com/lucasr/probe&#34;&gt;probe&lt;/a&gt; project came to mind.&lt;/p&gt;

&lt;p&gt;i decided to experiment and see if i could use probe to automatically add a ripple effect to a set of views without having to touch existing code. turns out it&amp;rsquo;s fairly easy to do! i did two separate implementations.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/probe_androidui.10.14.2014.gif&#34;&gt;&lt;img src=&#34;http://helw.net/images/probe_androidui.10.14.2014.gif&#34;
 width=&#34;288&#34;  
 height=&#34;513&#34;  &gt;
&lt;/a&gt; &lt;a href=&#34;http://helw.net/images/probe_widgets.10.14.2014.gif&#34;&gt;&lt;img src=&#34;http://helw.net/images/probe_widgets.10.14.2014.gif&#34;
 width=&#34;288&#34;  
 height=&#34;513&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the first image is using &lt;a href=&#34;https://github.com/markushi&#34;&gt;Markus Hi&amp;rsquo;s&lt;/a&gt; &lt;a href=&#34;https://github.com/markushi/android-ui&#34;&gt;android-ui&lt;/a&gt; library. the second image is using &lt;a href=&#34;https://github.com/MostafaGazar/Widgets&#34;&gt;Mostafa&amp;rsquo;s Widgets&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;the code using Mostafa&amp;rsquo;s Widgets is a lot simpler (due to RippleView doing most of the heavy lifting) - you can see it &lt;a href=&#34;https://gist.github.com/ahmedre/3a0a8accc7fec2bf1f2e&#34;&gt;here&lt;/a&gt;. the code for wrapping android-ui is a bit more complicated (and mimics what Mostafa does in RippleView) and can be found &lt;a href=&#34;https://gist.github.com/ahmedre/e6807cf729e3f25dd807&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;the general idea for both probe implementations is the same - we take any given view, and replace it with a FrameLayout containing the view, and an underlying &amp;ldquo;ripple view.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;now to apply either of these methods, we can do something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-java&#34;&gt;public class RippleActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    Probe.deploy(this, new RevealInterceptor(this),
        new Filter.ParentId(R.id.ripple_main));
    // can also use RippleInterceptor instead
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ripples);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;FrameLayout xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;
    android:id=&amp;quot;@+id/ripple_main&amp;quot;
    android:orientation=&amp;quot;vertical&amp;quot;
    android:layout_width=&amp;quot;match_parent&amp;quot;
    android:layout_height=&amp;quot;match_parent&amp;quot;&amp;gt;

    &amp;lt;View android:id=&amp;quot;@+id/button&amp;quot;
        android:layout_width=&amp;quot;128dp&amp;quot;
        android:layout_height=&amp;quot;128dp&amp;quot;
        android:background=&amp;quot;#aa00aaff&amp;quot;
        android:layout_gravity=&amp;quot;center&amp;quot; /&amp;gt;

    &amp;lt;View android:layout_gravity=&amp;quot;bottom&amp;quot;
        android:layout_width=&amp;quot;50dp&amp;quot;
        android:layout_height=&amp;quot;50dp&amp;quot;
        android:background=&amp;quot;#aaff&amp;quot; /&amp;gt;

&amp;lt;/FrameLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;one interesting point - if you remove the filter and just let probe work on any view (both interceptors enforce non-ViewGroups only), the ripple effect ends up working on all views, including views in the ActionBar as well (which is really neat!)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>saudi matches 1.0.1</title>
      <link>http://helw.net/2014/08/29/saudi-matches-1.0.1/</link>
      <pubDate>Fri, 29 Aug 2014 22:44:28 -0700</pubDate>
      
      <guid>http://helw.net/2014/08/29/saudi-matches-1.0.1/</guid>
      <description>&lt;p&gt;not too long back, i posted about &lt;a href=&#34;http://helw.net/2013/05/04/euro-matches-for-android/&#34;&gt;euro matches&lt;/a&gt;. earlier this year, we also pushed &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.matchesapp.saudi&#34;&gt;saudi matches&lt;/a&gt;. it includes a new ui, new features, and so on. saudi matches was done in conjunction with &lt;a href=&#34;https://twitter.com/Khalid&#34;&gt;Khalid Sudairy&lt;/a&gt;, &lt;a href=&#34;https://twitter.com/Bandar&#34;&gt;Bandar Raffah&lt;/a&gt;, and &lt;a href=&#34;https://twitter.com/taylorling&#34;&gt;Taylor Ling&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/saudi_list.08.29.2014.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/saudi_list.08.29.2014.png&#34;
 width=&#34;270&#34;  
 height=&#34;480&#34;  &gt;
&lt;/a&gt; &lt;a href=&#34;http://helw.net/images/saudi_match.08.29.2014.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/saudi_match.08.29.2014.png&#34;
 width=&#34;270&#34;  
 height=&#34;480&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;you can download it &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.matchesapp.saudi&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>quran plugin for alfred and launchbar</title>
      <link>http://helw.net/2014/08/10/quran-plugin-for-alfred-and-launchbar/</link>
      <pubDate>Sun, 10 Aug 2014 01:43:46 -0700</pubDate>
      
      <guid>http://helw.net/2014/08/10/quran-plugin-for-alfred-and-launchbar/</guid>
      <description>&lt;p&gt;several months ago, i posted a &lt;a href=&#34;http://helw.net/2011/06/01/search-quran-with-alfredapp-on-osx/&#34;&gt;plugin&lt;/a&gt; for searching the quran with alfred. i was playing with &lt;a href=&#34;http://www.obdev.at/products/launchbar/index.html&#34;&gt;launchbar 6&lt;/a&gt; recently, and while trying to figure out whether i want to use alfred or launchbar, i decided to write a plugin for searching the quran,
with suggestions, for launchbar.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;http://helw.net/images/quran.launchbar.08.10.2014.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/code/Quran.lbaction&#34;&gt;download the launchbar plugin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;i also decided to update the plugin for alfred (to have autocomplete). note that the current search api supports &lt;code&gt;in:en&lt;/code&gt; (in english), &lt;code&gt;in:tl&lt;/code&gt; (in transliteration), etc.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;http://helw.net/images/quran.alfred.08.10.2014.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/code/Quran.alfredworkflow&#34;&gt;download the alfred plugin&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>migrating from octopress to hexo</title>
      <link>http://helw.net/2014/07/29/migrating-from-octopress-to-hexo/</link>
      <pubDate>Tue, 29 Jul 2014 20:08:24 -0700</pubDate>
      
      <guid>http://helw.net/2014/07/29/migrating-from-octopress-to-hexo/</guid>
      <description>&lt;p&gt;it&amp;rsquo;s been a long time since my last blog post, but i am hoping to become better about blogging. anyhow, the other day, i found &lt;a href=&#34;getnikola.com&#34;&gt;nikola&lt;/a&gt;, a python blogging engine. i played with it and thought, &amp;ldquo;it would be cool to migrate my blog to it.&amp;rdquo; someone had written a migration script from octopress, and so i played with a migrated version locally.&lt;/p&gt;

&lt;p&gt;unfortunately, some things (like pagination) would break the existing model that i&amp;rsquo;ve been using on this site in the past. so after much searching, i found &lt;a href=&#34;http://hexo.io&#34;&gt;hexo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;hexo is &amp;ldquo;a fast, simple &amp;amp; powerful blog framework, powered by Node.js.&amp;rdquo; it&amp;rsquo;s also a static blogging engine.&lt;/p&gt;

&lt;p&gt;migrating from octopress was extremely simple - just a matter of copying pieces of my source directory to hexo&amp;rsquo;s source directory. then it was just a matter of tweaking some settings, finding a &lt;a href=&#34;https://github.com/hexojs/hexo-theme-light&#34;&gt;theme&lt;/a&gt;, and so on.&lt;/p&gt;

&lt;p&gt;why migrate? first, it seems that &lt;a href=&#34;http://octopress.org&#34;&gt;octopress&lt;/a&gt; development has slowed down (at least relative to some of these other engines). secondly, some things, like tags, were only supported via a third party script. third, i am hoping it helps me blog more.&lt;/p&gt;

&lt;p&gt;there you have it. enjoy!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>quranicaudio.com web update for ios7</title>
      <link>http://helw.net/2013/09/25/quranicaudio.com-web-update-for-ios7/</link>
      <pubDate>Wed, 25 Sep 2013 23:29:00 -0700</pubDate>
      
      <guid>http://helw.net/2013/09/25/quranicaudio.com-web-update-for-ios7/</guid>
      <description>&lt;p&gt;since ios7 brings such a huge change to the ui of ios, i&amp;rsquo;ve updated the web interface for quranicaudio.com for the iphone. here are the before/after pictures:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://helw.net/images/quranicaudio.web.before.09.25.2013.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/quranicaudio.web.before.09.25.2013.png&#34;
 width=&#34;320&#34;  
 height=&#34;480&#34;  &gt;
&lt;/a&gt; &lt;a href=&#34;http://helw.net/images/quranicaudio.web.after.09.25.2013.png&#34;&gt;&lt;img src=&#34;http://helw.net/images/quranicaudio.web.after.09.25.2013.png&#34;
 width=&#34;320&#34;  
 height=&#34;480&#34;  &gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;this was made a lot easier thanks to &lt;a href=&#34;http://www.ios7templates.com/&#34;&gt;ios7 templates&lt;/a&gt;. i realize that there is no support for android at the moment, but insha&amp;rsquo;Allah will hopefully get to this eventually since it is important to do (and nice to have).&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>