<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Android on Haoxiqiang&#39;s Blog</title>
    <link>https://blog.substitute.tech/en/categories/android/</link>
    <description>Recent content in Android on Haoxiqiang&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Mon, 15 Aug 2022 20:53:06 +0000</lastBuildDate>
    <atom:link href="https://blog.substitute.tech/en/categories/android/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Build AOSP for Pixel 3 XL</title>
      <link>https://blog.substitute.tech/en/posts/aosp-build-for-pixel3/</link>
      <pubDate>Mon, 15 Aug 2022 20:53:06 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/aosp-build-for-pixel3/</guid>
      <description>&lt;p&gt;The AOSP build process is fairly well understood by now: sync the source code, add device-specific drivers and kernel, and build the target image. I had built AOSP before to debug certain issues, but official support for Pixel 3 XL only goes up to Android 12. Recently, while working on Chromium development, I needed to test WebView on a newer platform, so I used LineageOS 21 for the build instead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Optimizing Android Builds with Self-Hosted Nexus Repository</title>
      <link>https://blog.substitute.tech/en/posts/nexus/</link>
      <pubDate>Tue, 31 Dec 2019 21:29:27 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/nexus/</guid>
      <description>&lt;p&gt;In Android dependency management, it&amp;rsquo;s common to configure multiple remote repositories like &lt;code&gt;jcenter&lt;/code&gt;, &lt;code&gt;jitpack&lt;/code&gt;, &lt;code&gt;google()&lt;/code&gt;, and more. Some large projects, such as &amp;ldquo;Zuiyou&amp;rdquo;, depend on over 10 repositories. This becomes a significant problem during initial project setup, dependency changes, or network issues — troubleshooting builds becomes a nightmare.&lt;/p&gt;
&lt;p&gt;I had noticed this issue long ago but kept putting off addressing it. This post documents the Nexus setup process.&lt;/p&gt;
&lt;h2 id=&#34;installing-and-configuring-nexus&#34;&gt;Installing and Configuring Nexus&lt;/h2&gt;
&lt;p&gt;Prerequisite: JDK 8+.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android MediaStore: GROUP BY via ContentResolver</title>
      <link>https://blog.substitute.tech/en/posts/android%E7%9A%84mediastore/</link>
      <pubDate>Fri, 31 Mar 2017 11:19:26 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/android%E7%9A%84mediastore/</guid>
      <description>&lt;p&gt;When building a photo album feature similar to WeChat, I needed to read photos and videos with multi-folder switching — and it had to be faster than WeChat. After some research, the &lt;code&gt;MediaStore&lt;/code&gt; approach proved most suitable. Since I hadn&amp;rsquo;t used it much before, this post serves as a record.&lt;/p&gt;
&lt;h2 id=&#34;the-group-by-hack-in-contentresolver&#34;&gt;The GROUP BY Hack in ContentResolver&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ContentResolver.query()&lt;/code&gt; does not expose a &lt;code&gt;groupBy&lt;/code&gt; parameter (unlike &lt;code&gt;SQLiteQueryBuilder.query()&lt;/code&gt;), but you can achieve a similar effect by embedding &lt;code&gt;GROUP BY&lt;/code&gt; directly into the &lt;code&gt;selection&lt;/code&gt; argument.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Issues Roundup (Part 2)</title>
      <link>https://blog.substitute.tech/en/posts/%E9%97%AE%E9%A2%98%E6%95%B4%E7%90%86%E4%BA%8C/</link>
      <pubDate>Tue, 19 Jan 2016 16:50:36 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/%E9%97%AE%E9%A2%98%E6%95%B4%E7%90%86%E4%BA%8C/</guid>
      <description>&lt;p&gt;Second batch of collected issues, mainly covering WebView memory management, cookie synchronization, and other development details.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building an App with RxJava</title>
      <link>https://blog.substitute.tech/en/posts/rxjava/</link>
      <pubDate>Thu, 07 Jan 2016 14:05:45 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/rxjava/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been working on a Zhihu Daily client to evaluate RxJava&amp;rsquo;s benefits and trade-offs in a real project. RxJava has gained significant traction abroad, with language bindings spanning Java, JavaScript, C#, Scala, Clojure, C++, Python, Ruby, Kotlin, Swift, and more.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Development Issues and Solutions</title>
      <link>https://blog.substitute.tech/en/posts/%E9%97%AE%E9%A2%98%E6%95%B4%E7%90%86/</link>
      <pubDate>Tue, 29 Dec 2015 18:41:05 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/%E9%97%AE%E9%A2%98%E6%95%B4%E7%90%86/</guid>
      <description>&lt;p&gt;After reading some issue roundups on Xiaoke&amp;rsquo;s Blog, I realized I&amp;rsquo;ve encountered many of the same problems. Here&amp;rsquo;s a collected summary.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Resource Shrinking</title>
      <link>https://blog.substitute.tech/en/posts/resourceshrinking%E8%B5%84%E6%BA%90%E6%B8%85%E7%90%86/</link>
      <pubDate>Wed, 23 Dec 2015 17:43:07 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/resourceshrinking%E8%B5%84%E6%BA%90%E6%B8%85%E7%90%86/</guid>
      <description>&lt;p&gt;While building a project, I discovered the &lt;code&gt;shrinkResources&lt;/code&gt; attribute, which removes unused resources from the APK. Here is how to configure it and what to watch out for.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tree View Menu with RecyclerView</title>
      <link>https://blog.substitute.tech/en/posts/treeview%E6%A0%91%E5%BD%A2%E8%8F%9C%E5%8D%95/</link>
      <pubDate>Wed, 16 Dec 2015 18:15:33 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/treeview%E6%A0%91%E5%BD%A2%E8%8F%9C%E5%8D%95/</guid>
      <description>&lt;p&gt;I had long wanted to write a tree view demo. Previously, I used &lt;code&gt;TreeViewList&lt;/code&gt; (a &lt;code&gt;ListView&lt;/code&gt; wrapper) or &lt;code&gt;ExpandableListView&lt;/code&gt; for multi-level menus. Eventually I realized there is no need for custom views &amp;ndash; just use &lt;code&gt;RecyclerView&lt;/code&gt; and manage the data flattening yourself.&lt;/p&gt;
&lt;p&gt;The core idea: recursively flatten a nested data structure into a linear list, then use &lt;code&gt;notifyItemRangeInserted&lt;/code&gt; / &lt;code&gt;notifyItemRangeRemoved&lt;/code&gt; to handle expand and collapse.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Solving Problems from Error Logs — Bugly Blog Collection</title>
      <link>https://blog.substitute.tech/en/posts/%E5%A6%82%E4%BD%95%E6%A0%B9%E6%8D%AE%E9%94%99%E8%AF%AF%E6%97%A5%E5%BF%97%E8%A7%A3%E5%86%B3%E9%97%AE%E9%A2%98/</link>
      <pubDate>Wed, 29 Jul 2015 12:00:39 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/%E5%A6%82%E4%BD%95%E6%A0%B9%E6%8D%AE%E9%94%99%E8%AF%AF%E6%97%A5%E5%BF%97%E8%A7%A3%E5%86%B3%E9%97%AE%E9%A2%98/</guid>
      <description>&lt;p&gt;We use Tencent Bugly for crash monitoring in our project. Most crash reporting tools are similar in functionality; Bugly was chosen for its clean statistics dashboard and reliable brand. Here is a curated collection of Bugly&amp;rsquo;s technical blog posts covering common crash scenarios and analysis approaches.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Common Issues When Customizing Volley</title>
      <link>https://blog.substitute.tech/en/posts/volley%E8%87%AA%E5%AE%9A%E4%B9%89%E4%B8%AD%E7%9A%84%E5%87%A0%E4%B8%AA%E9%97%AE%E9%A2%98%E7%9A%84%E5%8E%9F%E5%9B%A0/</link>
      <pubDate>Tue, 09 Jun 2015 17:30:15 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/volley%E8%87%AA%E5%AE%9A%E4%B9%89%E4%B8%AD%E7%9A%84%E5%87%A0%E4%B8%AA%E9%97%AE%E9%A2%98%E7%9A%84%E5%8E%9F%E5%9B%A0/</guid>
      <description>&lt;p&gt;While integrating Volley into a project, I encountered several common issues worth documenting. The following does not apply to Android 2.3 and below.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Downloading Android Source Code</title>
      <link>https://blog.substitute.tech/en/posts/android%E6%BA%90%E7%A0%81%E4%B8%8B%E8%BD%BD/</link>
      <pubDate>Thu, 04 Jun 2015 15:45:04 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/android%E6%BA%90%E7%A0%81%E4%B8%8B%E8%BD%BD/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Timeliness note&lt;/strong&gt;: The mirror URLs in this article were valid for a specific period. Both TUNA (Tsinghua) and USTC (Hefei) AOSP mirror addresses have changed multiple times. Always consult each mirror&amp;rsquo;s official help page for current URLs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;AOSP source is enormous (~70GB), making downloads from Google&amp;rsquo;s official servers via VPN painfully slow. Chinese mirrors offer much faster speeds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Make Your App the Default SMS App</title>
      <link>https://blog.substitute.tech/en/posts/defaultapp/</link>
      <pubDate>Mon, 18 May 2015 16:49:21 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/defaultapp/</guid>
      <description>&lt;p&gt;While using Google Messenger, I noticed it has a &amp;ldquo;set as default SMS app&amp;rdquo; feature. Here&amp;rsquo;s how it works.&lt;/p&gt;
&lt;p&gt;Starting from Android 4.4 KitKat, Google introduced the default SMS app mechanism. The official reasoning:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Some of you have built SMS apps using hidden APIs — a practice we discourage because hidden APIs may be changed or removed and new devices are not tested against them for compatibility. So, to provide you with a fully supported set of APIs for building SMS apps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In short, if you build well and have enough users, Google takes notice and provides official support.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Notes from Reading Android Documentation</title>
      <link>https://blog.substitute.tech/en/posts/%E6%9C%80%E8%BF%91%E5%8F%91%E7%8E%B0%E7%9A%84%E5%87%A0%E4%B8%AA%E6%B3%A8%E6%84%8F%E7%82%B9/</link>
      <pubDate>Mon, 11 May 2015 11:18:26 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/%E6%9C%80%E8%BF%91%E5%8F%91%E7%8E%B0%E7%9A%84%E5%87%A0%E4%B8%AA%E6%B3%A8%E6%84%8F%E7%82%B9/</guid>
      <description>&lt;p&gt;A collection of subtle but important details I noticed while reading the Android developer documentation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dart Web Apps on Android</title>
      <link>https://blog.substitute.tech/en/posts/dart/</link>
      <pubDate>Tue, 05 May 2015 17:46:58 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/dart/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Historical note&lt;/strong&gt;: This article was written in 2015 based on the old Dart toolchain (Dart Editor + Dartium). Dart has since moved entirely to the Flutter ecosystem and the &lt;code&gt;dart&lt;/code&gt; CLI toolchain. Content is kept for reference only.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can launch and debug Android web applications built with Dart without pre-compiling to JavaScript. To do this, you need &lt;strong&gt;Dart Editor&lt;/strong&gt; and &lt;strong&gt;Dart Content Shell&lt;/strong&gt;. Dart Content Shell is automatically installed on the Android device.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Strange Problems I Encountered Recently</title>
      <link>https://blog.substitute.tech/en/posts/recent-strangeproblem/</link>
      <pubDate>Tue, 21 Apr 2015 14:41:34 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/recent-strangeproblem/</guid>
      <description>&lt;p&gt;A collection of obscure Android development issues and their solutions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Data Storage</title>
      <link>https://blog.substitute.tech/en/posts/androiddatastorage/</link>
      <pubDate>Wed, 08 Apr 2015 11:38:49 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androiddatastorage/</guid>
      <description>&lt;p&gt;Android provides several options for persisting data, each suited to different use cases. Choosing the right storage method is critical for your app&amp;rsquo;s performance, security, and user experience.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android App Widgets</title>
      <link>https://blog.substitute.tech/en/posts/androidappwidgets/</link>
      <pubDate>Wed, 01 Apr 2015 10:37:26 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androidappwidgets/</guid>
      <description>&lt;p&gt;An App Widget is a miniature application view that can be embedded into other applications (such as the Home screen) and receive periodic updates. Common examples include weather widgets and music player controls.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;appwidget&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/appwidget.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Developer Requirements</title>
      <link>https://blog.substitute.tech/en/posts/androiddeveloperrequirements/</link>
      <pubDate>Wed, 01 Apr 2015 09:50:52 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androiddeveloperrequirements/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This article was written in 2015. Some toolchain details and version numbers are outdated and provided for historical reference only. For current Android development, please refer to &lt;a href=&#34;https://developer.android.com/studio&#34;&gt;Android Studio&lt;/a&gt; and the &lt;a href=&#34;https://developer.android.com/&#34;&gt;official Android Developers documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Remote Debugging on Android with Chrome</title>
      <link>https://blog.substitute.tech/en/posts/remotedebuggingonandroidwithchrome/</link>
      <pubDate>Tue, 24 Mar 2015 14:54:02 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/remotedebuggingonandroidwithchrome/</guid>
      <description>&lt;p&gt;Chrome DevTools supports remote debugging of web pages and WebView applications on Android devices. This feature is invaluable for mobile front-end development and hybrid app development, allowing you to use the full suite of desktop Chrome DevTools to debug mobile pages.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bezier Curve Practice</title>
      <link>https://blog.substitute.tech/en/posts/beziercurvepractice/</link>
      <pubDate>Wed, 04 Mar 2015 14:11:48 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/beziercurvepractice/</guid>
      <description>&lt;p&gt;Bézier curves are widely used in computer graphics to model smooth curves. They were independently developed by French engineers Pierre Bézier (Renault) and Paul de Casteljau (Citroën) in the 1960s.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Bézier_3_big&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/Be%CC%81zier_3_big.svg.png&#34;&gt;&lt;img alt=&#34;Bézier_3_big_gif&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/Be%CC%81zier_3_big.gif&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Property Animation</title>
      <link>https://blog.substitute.tech/en/posts/androidpropertyanimation/</link>
      <pubDate>Tue, 03 Mar 2015 10:31:21 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androidpropertyanimation/</guid>
      <description>&lt;p&gt;&lt;code&gt;Property Animation&lt;/code&gt; is a powerful animation framework introduced in Android 3.0 (API 11). Unlike the older View Animation (tween animation) system, property animation actually changes the properties of the target object, not just its rendered appearance.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLite Limits Explained: Tracing a SQLiteFullException</title>
      <link>https://blog.substitute.tech/en/posts/limitsinsqlite/</link>
      <pubDate>Sat, 28 Feb 2015 22:48:55 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/limitsinsqlite/</guid>
      <description>&lt;p&gt;While debugging a recent bug, I ran into a peculiar issue: &lt;code&gt;android.database.sqlite.SQLiteFullException: database or disk is full (code 13)&lt;/code&gt;. After extensive research without a definitive root cause, I am sharing my findings here in the hope that others with similar experiences can help shed light on this.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;limitsinsqlite01&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/limitsinsqlite01.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Notification Guide</title>
      <link>https://blog.substitute.tech/en/posts/androidnotification/</link>
      <pubDate>Thu, 29 Jan 2015 15:26:07 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androidnotification/</guid>
      <description>&lt;p&gt;The notification system is a critical channel for user-app interaction on Android — it keeps users informed of important events even when the app is not in the foreground, such as incoming messages or calendar reminders. Notifications received a major overhaul in Android 4.1 (Jelly Bean) and continued to see refinements through Android 5.0 (Lollipop). Since 4.1, Android supports action buttons at the bottom of notifications, allowing users to perform common tasks directly without opening the app.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This article was written for the Android 4.1–5.0 era APIs. Starting from Android 8.0 (API 26), all notifications must be assigned to a Notification Channel. Android 13 (API 33) introduced the &lt;code&gt;POST_NOTIFICATIONS&lt;/code&gt; runtime permission. The code examples below use &lt;code&gt;NotificationCompat&lt;/code&gt; for backward compatibility; visual results may vary across devices.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt=&#34;notification01&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/notification01.jpg&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Learning Resources Guide</title>
      <link>https://blog.substitute.tech/en/posts/android%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99%E6%8C%87%E5%8D%97/</link>
      <pubDate>Mon, 26 Jan 2015 16:35:07 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/android%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99%E6%8C%87%E5%8D%97/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Note: This post was written in 2015. Some links may no longer be valid. The recommendations reflect the ecosystem at that time, but the core learning path and methodology remain relevant.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;foreword&#34;&gt;Foreword&lt;/h2&gt;
&lt;p&gt;We all start somewhere. For any technology, everyone begins with Hello World. What puzzles me is why some people improve 100% in a year while others only 20% — or even stagnate. Is it IQ? In my opinion, it is more likely a matter of learning method.&lt;/p&gt;
&lt;p&gt;While on my wedding leave, I was writing blog posts and searching for learning materials. I found that relying solely on Baidu was terribly inefficient — at least half the time was wasted on useless pages. I decided to spend a few evenings organizing my bookmarks, making sure most resources are accessible from within China. The following is a curated list for beginner-to-intermediate Android developers. As for advanced-level topics — I&amp;rsquo;m not quite qualified to speak on those yet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Setting Up Android Environment, Source Code, and Tools Using Chinese Mirrors</title>
      <link>https://blog.substitute.tech/en/posts/%E8%BD%BB%E6%9D%BE%E6%90%9E%E5%AE%9Aandroid%E7%9A%84%E7%8E%AF%E5%A2%83%E6%BA%90%E7%A0%81%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Fri, 16 Jan 2015 08:35:07 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/%E8%BD%BB%E6%9D%BE%E6%90%9E%E5%AE%9Aandroid%E7%9A%84%E7%8E%AF%E5%A2%83%E6%BA%90%E7%A0%81%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This post was written in 2015. Some mirror URLs may have changed or become unavailable. As of 2025, the recommended mirrors for Chinese developers are Tsinghua TUNA, USTC, and other university mirrors, or simply using Android Studio&amp;rsquo;s built-in SDK Manager.&lt;/p&gt;
&lt;p&gt;For developers behind the Great Firewall of China, accessing Google&amp;rsquo;s servers directly is slow or unreliable. This post covers mirror-based solutions for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android SDK updates&lt;/li&gt;
&lt;li&gt;Android Studio downloads&lt;/li&gt;
&lt;li&gt;AOSP source code downloads&lt;/li&gt;
&lt;li&gt;Android NDK downloads&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Android Fragment$InstantiationException: Causes and Solutions</title>
      <link>https://blog.substitute.tech/en/posts/android-fragmentinstantiationexception/</link>
      <pubDate>Wed, 07 Jan 2015 08:35:07 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/android-fragmentinstantiationexception/</guid>
      <description>&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;android&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;support&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fragment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InstantiationException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Unable&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;instantiate&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fragment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;make&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sure&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exists&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;an&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;constructor&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;that&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This error used to be rare, but recently it spiked. After investigation, here are the causes and solutions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android EBUSY Exception</title>
      <link>https://blog.substitute.tech/en/posts/android-ebusy-exception/</link>
      <pubDate>Mon, 22 Dec 2014 15:35:07 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/android-ebusy-exception/</guid>
      <description>&lt;p&gt;While working on an image upload feature, I encountered a runtime exception on certain devices:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;java&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;FileNotFoundException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mnt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sdcard&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Android&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;com&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;xxxxxx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;android&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;files&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xxxx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;failed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EBUSY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Device&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;or&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;busy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;libcore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;IoBridge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IoBridge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;java&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;406&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;java&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;FileOutputStream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;init&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileOutputStream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;java&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;88&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Caused&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;by&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;libcore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ErrnoException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;failed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EBUSY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Device&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;or&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;busy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;libcore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;Posix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Native&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Method&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;libcore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;BlockGuardOs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlockGuardOs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;java&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;110&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Wireless Debugging on Android</title>
      <link>https://blog.substitute.tech/en/posts/android%E4%BD%BF%E7%94%A8wireless%E8%B0%83%E8%AF%95/</link>
      <pubDate>Fri, 05 Dec 2014 11:35:07 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/android%E4%BD%BF%E7%94%A8wireless%E8%B0%83%E8%AF%95/</guid>
      <description>&lt;p&gt;Ever since getting a Nexus device, I never wanted to plug in a USB cable again. Android supports ADB debugging over WiFi, making cable-free development a reality.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android&#39;s SQLite</title>
      <link>https://blog.substitute.tech/en/posts/androids-sqlite/</link>
      <pubDate>Mon, 01 Dec 2014 22:11:22 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androids-sqlite/</guid>
      <description>&lt;p&gt;SQLite is a lightweight relational database engine built into Android, ideal for local data persistence. The &lt;code&gt;android.database.sqlite&lt;/code&gt; package provides everything you need without additional setup.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android&#39;s Palette</title>
      <link>https://blog.substitute.tech/en/posts/androids-palette/</link>
      <pubDate>Mon, 03 Nov 2014 10:01:22 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androids-palette/</guid>
      <description>&lt;p&gt;The Palette library, part of Android Support Library (now migrated to AndroidX &lt;code&gt;palette&lt;/code&gt;), extracts representative colors from a Bitmap. In Material Design, deriving UI colors from imagery is a common pattern, and Palette makes this straightforward.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;palette01&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/palette01.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android RecyclerView (Part 2): Parallax Scrolling</title>
      <link>https://blog.substitute.tech/en/posts/androids-recyclerview2-%E8%A7%86%E5%B7%AE%E6%BB%9A%E5%8A%A8/</link>
      <pubDate>Sun, 02 Nov 2014 14:01:22 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androids-recyclerview2-%E8%A7%86%E5%B7%AE%E6%BB%9A%E5%8A%A8/</guid>
      <description>&lt;p&gt;Parallax scrolling is a common UI effect where different layers move at different speeds during scrolling, creating a sense of depth.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;parallaxrecycler&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/parallaxrecycler.gif&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android RecyclerView</title>
      <link>https://blog.substitute.tech/en/posts/androids-recyclerview/</link>
      <pubDate>Sat, 01 Nov 2014 17:03:26 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/androids-recyclerview/</guid>
      <description>&lt;p&gt;RecyclerView is a more flexible replacement for ListView. According to the official documentation, it efficiently maintains a limited collection of scrolling data items, and is recommended when your Views need to interact with user gestures and network data.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;RecyclerView01&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/RecyclerView01.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Canvas (Part 2): Clipping</title>
      <link>https://blog.substitute.tech/en/posts/android-canvas2/</link>
      <pubDate>Fri, 03 Oct 2014 14:19:06 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/android-canvas2/</guid>
      <description>&lt;p&gt;Canvas clipping limits the drawing region: only content within the clipped area is visible.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Canvas (Part 1)</title>
      <link>https://blog.substitute.tech/en/posts/android-canvas1/</link>
      <pubDate>Thu, 02 Oct 2014 13:19:06 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/android-canvas1/</guid>
      <description>&lt;p&gt;A View renders its content by &amp;ldquo;drawing&amp;rdquo; — using a canvas (&lt;code&gt;Canvas&lt;/code&gt;) and a paintbrush (&lt;code&gt;Paint&lt;/code&gt;). The &lt;code&gt;Canvas&lt;/code&gt; obtained through the &lt;code&gt;onDraw&lt;/code&gt; method is directly composited onto the View.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Canvas01&#34; loading=&#34;lazy&#34; src=&#34;https://blog.substitute.tech/images/android_canvas01.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android Custom View (Part 2): Measurement Modes</title>
      <link>https://blog.substitute.tech/en/posts/customview2/</link>
      <pubDate>Wed, 01 Oct 2014 19:19:06 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/customview2/</guid>
      <description></description>
    </item>
    <item>
      <title>Android Custom View (Part 1)</title>
      <link>https://blog.substitute.tech/en/posts/customview1/</link>
      <pubDate>Wed, 01 Oct 2014 17:19:06 +0000</pubDate>
      <guid>https://blog.substitute.tech/en/posts/customview1/</guid>
      <description>&lt;p&gt;When you first start writing custom Views in Android, it&amp;rsquo;s common to feel unsure where to begin. Generally, there are two approaches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;From scratch&lt;/strong&gt;: Extend &lt;code&gt;View&lt;/code&gt; and implement the appearance entirely through calculation and drawing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extend an existing View&lt;/strong&gt;: Add child views to an existing component, or override methods to change its behavior.&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
  </channel>
</rss>
