<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vignesh S</title>
    <description>The latest articles on DEV Community by Vignesh S (@svignesh93).</description>
    <link>https://dev.to/svignesh93</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F252303%2F1ac10ba9-97fc-4959-9c83-169ffd1571bf.png</url>
      <title>DEV Community: Vignesh S</title>
      <link>https://dev.to/svignesh93</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/svignesh93"/>
    <language>en</language>
    <item>
      <title>GitHub Actions for Android</title>
      <dc:creator>Vignesh S</dc:creator>
      <pubDate>Wed, 26 Aug 2020 10:09:13 +0000</pubDate>
      <link>https://dev.to/svignesh93/github-actions-for-android-1igl</link>
      <guid>https://dev.to/svignesh93/github-actions-for-android-1igl</guid>
      <description>&lt;p&gt;In this post, the "Android-InAppBilling" open source android application sample was used that leverages GitHub Actions CI.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Workflow:
&lt;/h3&gt;

&lt;p&gt;The "Android-InAppBilling" open source android app sample is based on Gradle build system. So, the workflow will run "gradlew" script on its machine to build the app.&lt;/p&gt;

&lt;p&gt;To accomplish this, created a new "build.yml" GitHub Actions Workflow file on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root_repo/.github/workflows/build.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In the "build.yml", the name of workflow is given as&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You can define your own workflow name, and you can create multiple workflows on the same project.&lt;/p&gt;

&lt;p&gt;The project has to build the code base on:&lt;/p&gt;

&lt;p&gt;1) whenever there is a change pushed to repository&lt;/p&gt;

&lt;p&gt;2) whenever there is a new Pull Request created for the repository&lt;/p&gt;

&lt;p&gt;To accomplish this, added the below changes on the workflow file:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  push:
    branches: [ main ] 
  pull_request:
    branches: [ main ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;After this, we have created a job where all of the work will be running on ubuntu.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  build:
    runs-on: ubuntu-latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This workflow uses predefined actions that will checkout to the main branch and uses JDK 1.8&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Then, we have granted executable permission for the "gradlew" script as "run" command to make a build as follows:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;After this, we first try to check the code base with lint tool:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    - name: Check Lint
      run: sudo ./gradlew lintDebug
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We used "sudo" here, just wanted to install missing Android SDK and the Build Tools.&lt;/p&gt;

&lt;p&gt;If it was successful, then we try to run tests...&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    - name: Run tests
      run: sudo ./gradlew test
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If all the test cases passed, then we try to build the app by:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    - name: Build with Gradle
      run: sudo ./gradlew build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The complete workflow file and the repository link included here with this post as below...&lt;/p&gt;
&lt;h3&gt;
  
  
  Yaml File:
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h3&gt;
  
  
  Link to Code:
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/LiteKite"&gt;
        LiteKite
      &lt;/a&gt; / &lt;a href="https://github.com/LiteKite/Android-InAppBilling"&gt;
        Android-InAppBilling
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A sample which uses Google's Play Billing Library and it does InApp Purchases and Subscriptions.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Android-InAppBilling&lt;/h1&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/LiteKite/Android-InAppBilling/blob/assets/assets/app_icon.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a2BvfTs9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/LiteKite/Android-InAppBilling/raw/assets/assets/app_icon.png" alt="App Icon"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
A sample which uses Google's Play Billing Library and it does InApp Purchases and Subscriptions.&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://codeclimate.com/github/LiteKite/Android-InAppBilling/maintainability" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/a77ef6ea94051daea93d834219b773206794cc8f/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f39303836636533656331303832636234353566612f6d61696e7461696e6162696c697479"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/LiteKite/Android-InAppBilling/workflows/build/badge.svg?branch=main"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QmSRDN9O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/LiteKite/Android-InAppBilling/workflows/build/badge.svg%3Fbranch%3Dmain" alt="build"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/LiteKite/Android-InAppBilling/blob/assets/assets/screen_one.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tTcyIkJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/LiteKite/Android-InAppBilling/raw/assets/assets/screen_one.png" alt="App Screenshot One"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/LiteKite/Android-InAppBilling/blob/assets/assets/screen_two.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FJ_DxHVh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/LiteKite/Android-InAppBilling/raw/assets/assets/screen_two.png" alt="App Screenshot Two"&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/LiteKite/Android-InAppBilling/blob/assets/assets/screen_three.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k7c_LYkU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/LiteKite/Android-InAppBilling/raw/assets/assets/screen_three.png" alt="App Screenshot Three"&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/LiteKite/Android-InAppBilling/blob/assets/assets/screen_four.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9iSnHGao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/LiteKite/Android-InAppBilling/raw/assets/assets/screen_four.png" alt="App Screenshot Four"&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/LiteKite/Android-InAppBilling/blob/assets/assets/screen_five.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x84HiXAw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/LiteKite/Android-InAppBilling/raw/assets/assets/screen_five.png" alt="App Screenshot Five"&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/LiteKite/Android-InAppBilling/blob/assets/assets/screen_six.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--My164cd6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/LiteKite/Android-InAppBilling/raw/assets/assets/screen_six.png" alt="App Screenshot Six"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;h2&gt;
Getting Started&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add Play Billing Library dependency in your Android Studio Project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use the Application ID that's been used in your Google Play Developer Console.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="3"&gt;
&lt;li&gt;
&lt;p&gt;Make In-app purchases by starting &lt;code&gt;BillingClient&lt;/code&gt; connection, make querying purchases locally or from Google Play Store Cache from &lt;code&gt;BillingClient&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In-app product or "Managed Products" can be bought multiple times by consuming purchase before requesting another purchase.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Subscription based products cannot be consumed, It'll be based on some time periods that you choose and will expire after the time ends. These are all handled by Google Play Remote Server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add Tester Accounts in Google Play Developer Console -&amp;gt; App Releases for making test purchases and upload the initial version of your project APK including Google Play Billing Library dependency.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
Libraries Used&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Play Billing Library&lt;/code&gt; -&amp;gt; for making Google Play In-app…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/LiteKite/Android-InAppBilling"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Phone Friendly&lt;/p&gt;

</description>
      <category>actionshackathon</category>
      <category>github</category>
      <category>android</category>
    </item>
    <item>
      <title>Android-Proguard</title>
      <dc:creator>Vignesh S</dc:creator>
      <pubDate>Mon, 10 Aug 2020 15:53:53 +0000</pubDate>
      <link>https://dev.to/svignesh93/android-proguard-566k</link>
      <guid>https://dev.to/svignesh93/android-proguard-566k</guid>
      <description>&lt;p&gt;Proguard on android obfuscates code into some random letters and it makes hard to reverse engineer the code from the published apk.&lt;/p&gt;

&lt;p&gt;Enabling proguard on a gradle build system is super easy as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gradle&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt;

&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;buildTypes&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;release&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;minifyEnabled&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="n"&gt;shrinkResources&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="n"&gt;proguardFiles&lt;/span&gt; &lt;span class="nf"&gt;getDefaultProguardFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'proguard-android-optimize.txt'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'proguard-rules.pro'&lt;/span&gt;
            &lt;span class="n"&gt;signingConfig&lt;/span&gt; &lt;span class="n"&gt;signingConfigs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;release&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Additionaly, enabling &lt;b&gt;shrinkResources&lt;/b&gt; will remove the unused code and it drastically reduces the size of the generated apk.&lt;/p&gt;

&lt;p&gt;After publishing your apk with proguard enabled and if your app crashes, throws exceptions or does not work properly, you will definitely get logs from third party crash analytics tool or you will try to get the logs directly by reproducing the steps.&lt;/p&gt;

&lt;p&gt;With proguard enabled, your stack trace or logs could look like the below one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;06-25 22:19:34.407 14270 14311 E AndroidRuntime: Process: com.litekite.example, PID: 14270
06-25 22:19:34.407 14270 14311 E AndroidRuntime: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8372)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1444)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.view.View.requestLayout(View.java:25010)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.view.View.requestLayout(View.java:25010)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at androidx.constraintlayout.widget.ConstraintLayout.requestLayout(Unknown Source:0)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.view.View.requestLayout(View.java:25010)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.view.View.requestLayout(View.java:25010)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.widget.ImageView.setImageDrawable(ImageView.java:597)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at androidx.appcompat.widget.AppCompatImageView.setImageDrawable(Unknown Source:0)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at d.b.p.m.c(Unknown Source:26)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at androidx.appcompat.widget.AppCompatImageView.setImageResource(Unknown Source:4)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at com.litekite.example.ui.u(Unknown Source:9)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at e.c.a.f.a.d.b(:4)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at e.c.a.h.a.a(:10)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at e.c.a.h.a$c.onCapabilitiesChanged(:3)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.net.ConnectivityManager$NetworkCallback.onAvailable(ConnectivityManager.java:3261)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at e.c.a.h.a$c.onAvailable(Unknown Source:0)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.net.ConnectivityManager$CallbackHandler.handleMessage(ConnectivityManager.java:3474)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:107)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:214)
06-25 22:19:34.407 14270 14311 E AndroidRuntime:        at android.os.HandlerThread.run(HandlerThread.java:67) 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;From the above stack trace, it is quite hard to find out the cause of the exception, because the code were obfuscated into some magical letters.&lt;/p&gt;

&lt;p&gt;To solve this problem, you really need to deobfuscate the stack trace to find out the cause.&lt;/p&gt;

&lt;p&gt;For this deobfuscation, download the &lt;b&gt;Retrace Script&lt;/b&gt; which is packaged with &lt;b&gt;Proguard&lt;/b&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Download retrace.sh from Guardsquare:

https://www.guardsquare.com/en/products/proguard/manual/retrace
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To deobfuscate the stack trace, you need to have two files as an input for this tool to generate the original stack trace.&lt;/p&gt;

&lt;p&gt;1) Mapping.txt file - has all the letter mappings of the obfuscated code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You can get this mapping file from your app build directory:

root_directory/SampleApp/app/build/outputs/mapping/&amp;lt;build-type&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can also upload your &lt;b&gt;mapping.txt&lt;/b&gt; to Google Play Store or some online crash analytics platform like Firebase that produces deobfuscated stack trace that can be downloaded for quick analysis.&lt;/p&gt;

&lt;p&gt;2) Stacktrace.txt file - the obfuscated stack trace.&lt;/p&gt;

&lt;p&gt;The last step that is required to get the original stack trace is to run the &lt;b&gt;retrace.sh&lt;/b&gt; tool script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ retrace.sh -verbose mapping.txt stacktrace.txt &amp;gt; original_stacktrace.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The original_stacktrace.txt file would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2020-06-25 20:11:49.091 5838-5867/com.litekite.example E/AndroidRuntime: FATAL EXCEPTION: ConnectivityThread
    Process: com.litekite.example, PID: 5838
    java.lang.IllegalArgumentException: No enum constant e.c.a.h.a.b.4
        at java.lang.Enum.valueOf(Enum.java:257)
        at com.litekite.example.wifi.WifiController$WifiLevel.valueOf(Unknown Source:2)
        at com.litekite.example.wifi.WifiController.updateWifiState(:4)
        at com.litekite.example.wifi.WifiController$networkCallback$1.com.litekite.example.wifi.WifiController.access$updateWifiState(:3)
                                                                       onCapabilitiesChanged
        at android.net.ConnectivityManager$NetworkCallback.onAvailable(ConnectivityManager.java:3261)
        at com.litekite.example.wifi.WifiController$networkCallback$1.com.litekite.example.wifi.WifiController.access$setSsid$p(Unknown Source:0)
                                                                       onAvailable
                                                                       onAvailable
                                                                       com.litekite.example.wifi.WifiController.access$updateWifiState
                                                                       onAvailable
        at android.net.ConnectivityManager$CallbackHandler.handleMessage(ConnectivityManager.java:3474)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.os.HandlerThread.run(HandlerThread.java:67)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Restoring a stack trace with line numbers will require the below extra options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>android</category>
      <category>proguard</category>
      <category>obfuscation</category>
    </item>
  </channel>
</rss>
