Coder Social home page Coder Social logo

hackernews's Introduction

Hacker News

Come chat with us on Gitter.im!

Come chat with us!

Screenshot of the app

An open source Hacker News client for Android phones & tablets.

Get it on Google Play!

Available on the Google Play Store

How to build

The basic outline is this: there are 6 jars in the libs folder that the project depends on. Additionally you need one of my library projects, HoloTheme. It's basically a collection of utility classes & method's I've built up over time. HoloTheme also has a dependency on android-support-v4.jar (as does HackerNews).

To get what you need, run these commands from a shell:

git clone https://github.com/bishopmatthew/HackerNews.git
cd HackerNews/libs
git clone https://github.com/bishopmatthew/HoloTheme.git
IntelliJ

In IntelliJ, add HoloTheme as a module and create a module dependency from HackerNews on HoloTheme. Then create a library out of the 6 jars, and add it as a compile dependency to HackerNews and a provided dependency to HoloTheme.

Eclipse

I haven't used Eclipse in a while, but you should be able to add HoloTheme as a library project. Then add the 6 jars to the build path of HackerNews if it doesn't happen automatically. You may also have to copy android-support-v4 from HackerNews/libs into HackerNews/libs/HoloTheme/libs.

Android Studio

If you're using Android Studio:

  • Go into File > Project Structure... and add the HoloTheme repository you cloned earlier as Android Library modules (Modules > New Module > Library Module under the Android section in the New Module dialog).
  • Under the HoloTheme module, add all the jars in the ./libs/ folder as "provided" dependencies.
  • Under the HackerNews module, add all of the jars in the ./libs/ folder as "compile" dependencies.
  • Under the HackerNews module, add the HoloThememodule as dependencies (Using the Module Dependency option when adding them).

Design Overview

I've outlined the design in in this wiki article. This might also be helpful if you're interested in writing Android apps.

How to help

If you tackle any of the issues on the tracker, that would be great! I've added a few enhancements there with a pretty detailed description of what needs to be done.

License

The MIT License (MIT) Copyright (c) 2013 Matthew Bishop

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

The code will be here later today, for now you can use issues for bug reports or feature requests.

hackernews's People

Contributors

anselina avatar bishopmatthew avatar everlag avatar pkillian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hackernews's Issues

Crashes when mUsername and mPage are both null

http://crashes.to/s/bc8d7d21a0e

java.lang.RuntimeException: An error occured while executing doInBackground()
       at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:137)
       at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
       at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
       at java.util.concurrent.FutureTask.run(FutureTask.java:239)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.RuntimeException: Both the username & page passed to StoryLoader were null
       at com.airlocksoftware.hackernews.loader.StoryLoader.loadInBackground(StoryLoader.java:54)
       at com.airlocksoftware.hackernews.loader.StoryLoader.loadInBackground(StoryLoader.java:19)
       at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:242)
       at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
       at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
       at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
       at java.util.concurrent.FutureTask.run(FutureTask.java:234)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:841)

Force close in CommentsLoader

Stacktrace

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:137)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.NullPointerException
at com.airlocksoftware.hackernews.loader.CommentsLoader.loadInBackground(CommentsLoader.java:79)
at com.airlocksoftware.hackernews.loader.CommentsLoader.loadInBackground(CommentsLoader.java:1)
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
... 3 more

Sharing doesn't support apps with multiple sharing actions

For example, I'm using Pinboard and it has two actions add bookmark and add readlater. When I select one of them from the share list, Hacker News 2 will ask me again which one I want to complete the action. If I set one of the two as default ( always ), the other will be no longer available.

java.lang.OutOfMemoryError: bitmap size exceeds VM budget

Crash on slower / older devices, especially when switching between fragments / activities quickly. Related to creating a lot of bitmaps for my IconViews.

01-31 13:53:08.640: E/AndroidRuntime(27351): FATAL EXCEPTION: main 01-31 13:53:08.640: E/AndroidRuntime(27351): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.airlocksoftware.hackernews/com.airlocksoftware.hackernews.activity.MainActivity}: android.view.InflateException: Binary XML file line #36: Error inflating class <unknown> 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.os.Handler.dispatchMessage(Handler.java:99) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.os.Looper.loop(Looper.java:130) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.app.ActivityThread.main(ActivityThread.java:3683) 01-31 13:53:08.640: E/AndroidRuntime(27351): at java.lang.reflect.Method.invokeNative(Native Method) 01-31 13:53:08.640: E/AndroidRuntime(27351): at java.lang.reflect.Method.invoke(Method.java:507) 01-31 13:53:08.640: E/AndroidRuntime(27351): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 01-31 13:53:08.640: E/AndroidRuntime(27351): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 01-31 13:53:08.640: E/AndroidRuntime(27351): at dalvik.system.NativeStart.main(Native Method) 01-31 13:53:08.640: E/AndroidRuntime(27351): Caused by: android.view.InflateException: Binary XML file line #36: Error inflating class <unknown> 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.view.LayoutInflater.createView(LayoutInflater.java:518) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:570) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.view.LayoutInflater.rInflate(LayoutInflater.java:623) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.view.LayoutInflater.rInflate(LayoutInflater.java:626) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.view.LayoutInflater.inflate(LayoutInflater.java:383) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 01-31 13:53:08.640: E/AndroidRuntime(27351): at com.airlocksoftware.hackernews.view.TextSettingsOverflow.<init>(TextSettingsOverflow.java:72) 01-31 13:53:08.640: E/AndroidRuntime(27351): at com.airlocksoftware.hackernews.activity.MainActivity.setupSearchAndTextSettingsOverflow(MainActivity.java:430) 01-31 13:53:08.640: E/AndroidRuntime(27351): at com.airlocksoftware.hackernews.activity.MainActivity.onCreate(MainActivity.java:225) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 01-31 13:53:08.640: E/AndroidRuntime(27351): ... 11 more 01-31 13:53:08.640: E/AndroidRuntime(27351): Caused by: java.lang.reflect.InvocationTargetException 01-31 13:53:08.640: E/AndroidRuntime(27351): at java.lang.reflect.Constructor.constructNative(Native Method) 01-31 13:53:08.640: E/AndroidRuntime(27351): at java.lang.reflect.Constructor.newInstance(Constructor.java:415) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.view.LayoutInflater.createView(LayoutInflater.java:505) 01-31 13:53:08.640: E/AndroidRuntime(27351): ... 22 more 01-31 13:53:08.640: E/AndroidRuntime(27351): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.graphics.Bitmap.nativeCreate(Native Method) 01-31 13:53:08.640: E/AndroidRuntime(27351): at android.graphics.Bitmap.createBitmap(Bitmap.java:477) 01-31 13:53:08.640: E/AndroidRuntime(27351): at com.airlocksoftware.holo.image.IconView.generateBitmap(IconView.java:210) 01-31 13:53:08.640: E/AndroidRuntime(27351): at com.airlocksoftware.holo.image.IconView.generateDrawables(IconView.java:185) 01-31 13:53:08.640: E/AndroidRuntime(27351): at com.airlocksoftware.holo.image.IconView.<init>(IconView.java:87) 01-31 13:53:08.640: E/AndroidRuntime(27351): ... 25 more

Inconsistent scroll bar design in comments

When scrolling slowly through comments, the scroll bar switches between the standard android scroll bar style and the orange scroll bar style.
Device is a nexus 4 4.2.2 stock

Add "Clear Cache" button to settings

Occasionally something gets screwed up in the database that caches stories / comments. As a quick fix, it would be good to add a "Clear cache" button to the Settings activity.

Comment context menu doesn't appear for the last comment

The menu bar with the Upvote, Share, User and Reply buttons that appears when you long tap a comment, doesn't appear when l long tapping the last comment on a story. (Maybe this is to discourage people from replying to the worst comment on a thread? :)

Improve error message

The error message mentions a network problem, but it's more of a catch all for any problem with downloading and parsing the HTML from Hacker News. There error message should still mention the possibility of network problems, but should also mention that it may be an error with the Hacker News site, or with the app's parsing of the content.

Submitting to AskHN claims no connection/fail, results in spamming

When submitting a new AskHN post, the process always claims to fail due to connection issues while in fact posting to the board in the background (both with and without WiFi enabled on 4.3, Kernel 3.4.0-1625098 on a SM-N900A). This resulted in me spamming the board over 13 times in a couple hours. :(

My guess would be the culprit is somewhere around line 265 in src/com/airlocksoftware/hackernews/activity /SubmitActivity.java where neither success or failure is returned due to a perceived connection issue, and the submitting process continues.

Upon further investigation, is there some submit caching system in place? I haven't hit submit through the app in over 9 hours, yet it is still posting new submissions consistently about every 20 minutes.

Write tests!

I still haven't figured out how to effectively test Android apps. If anyone has any suggestions of which testing library to use, how to set it up, and examples of what to test, that would be amazing.

Unable to collapse last top level thread.

Doing so only collapses a single post rather than the post and all its children.

In the below screenshot, everything below dkhenry's post should have been hidden and the result being: dkhenry 5 children.

2013-12-24 16 30 33

Crash in the SlidingMenu -- CustomViewAbove.java line 607

java.lang.IndexOutOfBoundsException
at android.graphics.Paint.getTextRunAdvances(Paint.java:1731)
at android.graphics.Paint.getTextRunAdvances(Paint.java:1704)
at android.text.MeasuredText.addStyleRun(MeasuredText.java:164)
at android.text.MeasuredText.addStyleRun(MeasuredText.java:204)
at android.text.StaticLayout.generate(StaticLayout.java:281)
at android.text.DynamicLayout.reflow(DynamicLayout.java:284)
at android.text.DynamicLayout.(DynamicLayout.java:170)
at android.widget.TextView.makeSingleLayout(TextView.java:5843)
at android.widget.TextView.makeNewLayout(TextView.java:5741)
at android.widget.TextView.onMeasure(TextView.java:6098)
at android.view.View.measure(View.java:15172)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:617)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:399)
at android.view.View.measure(View.java:15172)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15172)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1038)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:576)
at android.view.View.measure(View.java:15172)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15172)
at android.widget.ListView.setupChild(ListView.java:1847)
at android.widget.ListView.makeAndAddView(ListView.java:1772)
at android.widget.ListView.fillDown(ListView.java:672)
at android.widget.ListView.fillSpecific(ListView.java:1330)
at android.widget.ListView.layoutChildren(ListView.java:1612)
at android.widget.AbsListView.onLayout(AbsListView.java:2104)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1388)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:948)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at com.slidingmenu.lib.CustomViewAbove.onLayout(CustomViewAbove.java:607)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:948)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:13754)
at android.view.ViewGroup.layout(ViewGroup.java:4362)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1866)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1687)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:525)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4899)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
at dalvik.system.NativeStart.main(Native Method)

Network error when trying to open a poll

For example, the AMA poll thread. At this time, I don't want to write the extra code to support displaying the poll options and actually allow voting (someone else is certainly free to do so). But it should at least display the title, selfText, and comments correctly.

Rotating the screen causes the embedded browser to refresh

When I visit an article through the app and rotate my screen, the page refreshes (which can cause quite a bit of delay sometimes). The real annoyance with this is that if I look at an article and then click on a link, causing a rotate event will reload first page (that is, the page linked to from HN) is what's loaded, instead of the one I was just on.

Really great job on this app, though. It's a pleasure to use!

Back button doesn't return you to search results

This is related to #17 because this app doesn't use the Android activity back stack normally. By the way this was a bad architecture decision that will need to be fixed eventually -- the app show probably become single activity and only use Fragments. I didn't do this originally because animations don't work properly with Fragments on Android 2.3.

Basically there are lots of ways to end up on the MainActivity, which shows the Story list and Comments page on both phones and tablets. This leads to the possibility of moving in a loop which grows the Activity back stack (and crashes somewhere around 8 activities). For example Story -> Comments -> Search -> Comments -> User -> Comments -> Search -> Comments... etc.

To combat this, the app currently has the MainActivity set to singleTask="true", and most other activities finish themselves before moving to another activity. Whenever the user goes "back" we're actually faking it by creating a new activity but playing the "back" animation.

There are two possible fixes:

  1. Pass additional information between activities to fake the back stack better (i.e. search terms, list scroll position)
  2. Switch to a single Activity, and just use Fragments everywhere. The Fragment back stack doesn't seem to have the same size limitations of the Activity back stack

Link inside app is not opened in new tab

When i open a link from inside the app, it is not opened in new tab; instead it overwrites my current opening tab on Chrome.

I am new to Android dev and still learning (i'm also trying to write a blog reader app) , so i don't know how complicated it is to fix this bug. But i like the app and really wants to contribute, so if you think i am capable, please leave this bug to me. We can discuss here to tackle the problem

FC when opening HackNews

Hey,
Matt, I've successfully built HackNews myself including dependency config(2 projects and 5 jar library ). However when I run the project using USB debugging, I got the following logcat.
Is anything wrong?

03-02 23:14:22.275: I/ActivityManager(505): Start proc com.airlocksoftware.hackernews for activity com.airlocksoftware.hackernews/.activity.MainActivity: pid=8991 uid=10114 gids={50114, 3003, 1028}
03-02 23:14:22.315: W/dalvikvm(8991): Unable to resolve superclass of Lcom/airlocksoftware/holo/activities/SlidingFragmentActivity; (71)
03-02 23:14:22.315: W/dalvikvm(8991): Link of class 'Lcom/airlocksoftware/holo/activities/SlidingFragmentActivity;' failed
03-02 23:14:22.315: W/dalvikvm(8991): Unable to resolve superclass of Lcom/airlocksoftware/holo/activities/ActionBarActivity; (354)
03-02 23:14:22.315: W/dalvikvm(8991): Link of class 'Lcom/airlocksoftware/holo/activities/ActionBarActivity;' failed
03-02 23:14:22.315: W/dalvikvm(8991): Unable to resolve superclass of Lcom/airlocksoftware/hackernews/activity/SlideoutMenuActivity; (353)
03-02 23:14:22.315: W/dalvikvm(8991): Link of class 'Lcom/airlocksoftware/hackernews/activity/SlideoutMenuActivity;' failed
03-02 23:14:22.315: W/dalvikvm(8991): Unable to resolve superclass of Lcom/airlocksoftware/hackernews/activity/MainActivity; (229)
03-02 23:14:22.315: W/dalvikvm(8991): Link of class 'Lcom/airlocksoftware/hackernews/activity/MainActivity;' failed
03-02 23:14:22.315: D/AndroidRuntime(8991): Shutting down VM
03-02 23:14:22.315: W/dalvikvm(8991): threadid=1: thread exiting with uncaught exception (group=0x40ee6930)
03-02 23:14:22.315: E/AndroidRuntime(8991): FATAL EXCEPTION: main
03-02 23:14:22.315: E/AndroidRuntime(8991): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.airlocksoftware.hackernews/com.airlocksoftware.hackernews.activity.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.airlocksoftware.hackernews.activity.MainActivity" on path: /data/app/com.airlocksoftware.hackernews-2.apk
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2106)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.os.Looper.loop(Looper.java:137)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.app.ActivityThread.main(ActivityThread.java:5041)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at java.lang.reflect.Method.invokeNative(Native Method)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at java.lang.reflect.Method.invoke(Method.java:511)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at dalvik.system.NativeStart.main(Native Method)
03-02 23:14:22.315: E/AndroidRuntime(8991): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.airlocksoftware.hackernews.activity.MainActivity" on path: /data/app/com.airlocksoftware.hackernews-2.apk
03-02 23:14:22.315: E/AndroidRuntime(8991):     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:65)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
03-02 23:14:22.315: E/AndroidRuntime(8991):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
03-02 23:14:22.315: E/AndroidRuntime(8991):     ... 11 more

Automatically reorder share list based on usage.

It'd be awesome if the share list was reordered based on last recently used (e.g. like Gallery sharing).

I never use Messing to share articles, but I use Google+ and Pocket pretty often. I'm sure this differs from person to person so it'd be nice if the list automatically rearranged itself.

Lower level logging for debugging purposes

Including Log.d() calls that include the activity's name, a brief message about what method is being called, and possible state information would be incredibly beneficial for debugging. I'll add more and more logging statements as I go along, and attribute any of them that aren't affiliated with other issues to this one.

Crash from bug in TextView

java.lang.IndexOutOfBoundsException
at android.graphics.Paint.getTextRunAdvances(Paint.java:1731)
at android.graphics.Paint.getTextRunAdvances(Paint.java:1704)
at android.text.MeasuredText.addStyleRun(MeasuredText.java:164)
at android.text.MeasuredText.addStyleRun(MeasuredText.java:204)
at android.text.StaticLayout.generate(StaticLayout.java:281)
at android.text.DynamicLayout.reflow(DynamicLayout.java:284)
at android.text.DynamicLayout.<init>(DynamicLayout.java:170)
at android.widget.TextView.makeSingleLayout(TextView.java:5843)
at android.widget.TextView.makeNewLayout(TextView.java:5741)
at android.widget.TextView.onMeasure(TextView.java:6117)
at android.view.View.measure(View.java:15172)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:617)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:399)
at android.view.View.measure(View.java:15172)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15172)
at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1212)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:576)
at android.view.View.measure(View.java:15172)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15172)
at android.widget.ListView.setupChild(ListView.java:1847)
at android.widget.ListView.makeAndAddView(ListView.java:1772)
at android.widget.ListView.fillDown(ListView.java:672)
at android.widget.ListView.fillGap(ListView.java:636)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5048)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3195)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3469)
at android.view.View.dispatchTouchEvent(View.java:7127)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2170)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1905)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1925)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1379)
at android.app.Activity.dispatchTouchEvent(Activity.java:2396)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1873)
at android.view.View.dispatchPointerEvent(View.java:7307)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3172)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3117)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4153)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4132)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4224)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:163)
at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4203)
at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4243)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:523)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4966)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
at dalvik.system.NativeStart.main(Native Method)

Fix is to add the code in this gist to FontText.java

Crash on open on Android 4.4

Stack trace:

java.lang.NullPointerException
  at com.bugsense.trace.Utils.manageUid(Unknown Source)
  at com.bugsense.trace.BugSenseHandler$1.run(Unknown Source)
  at java.lang.Thread.run(Thread.java:841)

I turned of the bug reporting in the settings and it doesn't seem to make a difference, so I assume it's probably coming from the init originating at SlideoutMenuActivity.java#L65

This was working fine on 4.3, so perhaps BugSense isn't playing nice with some change in KitKat.

Also, I've already submitted the crash report via the feedback mechanism in the developer console.

Planning for version 3.0

Here's a rough overview of what I'd like to see done in the app in the coming months. I've been very busy, so I'm not sure how much time I'll have to work on this, but I'd love anyone who can help to jump in. I'm happy to help support / answer questions / get you familiar with the codebase, so just ask.

Dev Stuff -- make the app easier to develop

  1. Move build process to Gradle and dev environment to Android Studio. This will have the added benefit of making it easier for people to get started with contributing.
  2. Move to support 4.0+ only. There's only 7% of the users on 2.3 and below, and they should be able to continue using the current version. This means we'll eventually be able to get rid of the library project dependencies.
  3. Undo some bad decision making / update to more recent versions of things. For example, instead of using sw-600dp folder for deciding which layout to give tablets, the app currently does it's own calculation. I'd also like to move from the custom ActionBarView implementation to the real thing, and use the Navigation Drawer instead of the old SidingMenu lib we're currently using. What is a fragment and what is an activity should also be rethought.
  4. Use Square open source everywhere! Move to OkHttp for the HTTP client, and move to Retrofit for interacting with the Search API. Start using Otto to send events around, instead of implementing callbacks for inter-fragment communication. Use Dagger for dependency injection, and Butterknife for view injection
  5. Unit testing -- use Espresso for UI testing, and probably use the built-in stuff for general testing

Features

  1. Support for opening links from other apps to news.ycombinator.com in the app.
  2. Keep search on the back stack so user can return to their search results after viewing something.
  3. Improve performance -- especially downloading, parsing, and possibly list scrolling performance
  4. Update the design -- there are some things I would like to improve on
  5. Gesture support -- I'd like to be able to return to the Story list with a gesture

Community

I'd love to get more people involved in the development of the app. One idea is to put together a Google Plus community so we can do beta testing there. Any other ideas?

If anyone has any ideas or comments, I'd be happy to hear about them!

Null pointer exception in CommentsLoader

java.lang.RuntimeException: An error occured while executing doInBackground() at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:137) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352) at java.util.concurrent.FutureTask.setException(FutureTask.java:219) at java.util.concurrent.FutureTask.run(FutureTask.java:239) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.NullPointerException at com.airlocksoftware.hackernews.loader.CommentsLoader.loadInBackground(CommentsLoader.java:85) at com.airlocksoftware.hackernews.loader.CommentsLoader.loadInBackground(CommentsLoader.java:1) at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240) at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51) at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40) at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123) at java.util.concurrent.FutureTask.run(FutureTask.java:234) ... 3 more

StoryFragment disappears after app is resumed -- if you click on refresh it will then crash

02-02 01:05:11.966: E/AndroidRuntime(10849): FATAL EXCEPTION: ModernAsyncTask #1 02-02 01:05:11.966: E/AndroidRuntime(10849): java.lang.RuntimeException: An error occured while executing doInBackground() 02-02 01:05:11.966: E/AndroidRuntime(10849): at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:137) 02-02 01:05:11.966: E/AndroidRuntime(10849): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352) 02-02 01:05:11.966: E/AndroidRuntime(10849): at java.util.concurrent.FutureTask.setException(FutureTask.java:219) 02-02 01:05:11.966: E/AndroidRuntime(10849): at java.util.concurrent.FutureTask.run(FutureTask.java:239) 02-02 01:05:11.966: E/AndroidRuntime(10849): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 02-02 01:05:11.966: E/AndroidRuntime(10849): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 02-02 01:05:11.966: E/AndroidRuntime(10849): at java.lang.Thread.run(Thread.java:856) 02-02 01:05:11.966: E/AndroidRuntime(10849): Caused by: java.lang.RuntimeException: Both the username & page passed to StoryLoader were null 02-02 01:05:11.966: E/AndroidRuntime(10849): at com.airlocksoftware.hackernews.loader.StoryLoader.loadInBackground(StoryLoader.java:56) 02-02 01:05:11.966: E/AndroidRuntime(10849): at com.airlocksoftware.hackernews.loader.StoryLoader.loadInBackground(StoryLoader.java:1) 02-02 01:05:11.966: E/AndroidRuntime(10849): at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240) 02-02 01:05:11.966: E/AndroidRuntime(10849): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51) 02-02 01:05:11.966: E/AndroidRuntime(10849): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40) 02-02 01:05:11.966: E/AndroidRuntime(10849): at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123) 02-02 01:05:11.966: E/AndroidRuntime(10849): at java.util.concurrent.FutureTask.run(FutureTask.java:234) 02-02 01:05:11.966: E/AndroidRuntime(10849): ... 3 more

Open Hacker News via intents from other apps

It would be nice if we could open the HN app for comment pages from other apps via the intent system. Example: when viewing search results in Google Now, clicking a result linking to a HN comment page should pop up Hacker News as a choice in the "Complete action using" dialog box. Clicking the choice should open the comments page on HN directly.

Keep an eye on repo size

As of 2013-01-03, the HackerNews repo is 7.78 MB and HoloTheme is 2.55 MB. If they much bigger (say over 15 MB total) it's probably time to clean them up with something like this script.

Force close when trying to save list state in StoryFragment

I seem to have introduced this when I added saving the list position to SharedPreferences. By the way, we have to save the list position to SharedPreferences (instead of a to a bundle) because StoryFragment is actually finished when we switch to the comments page. In the next version we should switch it so that (almost) everything is a fragment and thus we won't have the same issues with a circular back stack.

Stack trace:

FATAL EXCEPTION
java.lang.RuntimeException: Unable to pause activity {com.airlocksoftware.hackernews/com.airlocksoftware.hackernews.activity.MainActivity}: java.lang.NullPointerException
       at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2916)
       at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2872)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3559)
       at android.app.ActivityThread.access$800(ActivityThread.java:140)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4947)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
       at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.NullPointerException
       at com.airlocksoftware.hackernews.fragment.StoryFragment.onPause(StoryFragment.java:161)
       at android.support.v4.app.Fragment.performPause(Fragment.java:1661)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
       at android.support.v4.app.FragmentManagerImpl.dispatchPause(FragmentManager.java:1898)
       at android.support.v4.app.FragmentActivity.onPause(FragmentActivity.java:412)
       at android.app.Activity.performPause(Activity.java:5305)
       at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1240)
       at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2903)
       at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2872)
       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3559)
       at android.app.ActivityThread.access$800(ActivityThread.java:140)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4947)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
       at dalvik.system.NativeStart.main(NativeStart.java)

Downvote and flagging support?

It'd be nice if we had the option of downvoting posts and flagging threads in the app. Here's an example HTML dump for this Hacker News post:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="news.css?dcN9cPbvRlMWD01W5zH7">
    <link rel="shortcut icon" href="favicon.ico">
    <script type="text/javascript">
      function byId(id) {
        return document.getElementById(id);
      }

      function vote(node) {
        var v = node.id.split(/_/);   // {'up', '123'}
        var item = v[1]; 

        // hide arrows
        byId('up_'   + item).style.visibility = 'hidden';
        byId('down_' + item).style.visibility = 'hidden';

        // ping server
        var ping = new Image();
        ping.src = node.href;

        return false; // cancel browser nav
      } 
    </script>
    <title>What happens when our software has broken privacy settings | Hacker News</title>
  </head>
  <body>
    <center>
      <table border=0 cellpadding=0 cellspacing=0 width="85%" bgcolor=#f6f6ef>
        <tr>
          <td bgcolor=#ff6600>
            <table border=0 cellpadding=0 cellspacing=0 width="100%" style="padding:2px">
              <tr>
                <td style="width:18px;padding-right:4px"><a href="http://ycombinator.com"><img src="y18.gif" width=18 height=18 style="border:1px #ffffff solid;"></img></a></td>
                <td style="line-height:12pt; height:10px;"><span class="pagetop"><b><a href="news">Hacker News</a></b><img src="s.gif" height=1 width=10><a href="newest">new</a> | <a href="threads?id=wting">threads</a> | <a href="newcomments">comments</a> | <a href="ask">ask</a> | <a href="jobs">jobs</a> | <a href="submit">submit</a></span></td>
                <td style="text-align:right;padding-right:4px;"><span class="pagetop"><a href="user?id=wting">wting</a>&nbsp;(1921)&nbsp;|&nbsp;<a href="logout?whence=%69%74%65%6d%3f%69%64%3d%37%30%31%32%38%33%32">logout</a></span></td>
              </tr>
            </table>
          </td>
        </tr>
        <tr style="height:10px"></tr>
        <tr>
          <td>
            <table border=0>
              <tr>
                <td>
                  <center>
                    <a id=up_7012832 onclick="return vote(this)" href="vote?for=7012832&amp;dir=up&amp;by=wting&amp;auth=9255dbf7ede3eca957accf577aa96260c6f86d11&amp;whence=%69%74%65%6d%3f%69%64%3d%37%30%31%32%38%33%32">
                      <div class="votearrow" title="upvote"></div>
                    </a>
                    <span id=down_7012832></span>
                  </center>
                </td>
                <td class="title"><a href="http://www.reddit.com/r/technology/comments/1ueswk/what_happens_when_our_software_has_broken_privacy/" rel="nofollow">What happens when our software has broken privacy settings</a><span class="comhead"> (reddit.com) </span></td>
              </tr>
              <tr>
                <td colspan=1></td>
                <td class="subtext"><span id=score_7012832>1 point</span> by <a href="user?id=stesch">stesch</a> 4 minutes ago  | <a href="/r?fnid=0D0fYhyHOyYVK1QQJNyv8r">flag</a> | <a href="item?id=7012832">1 comment</a></td>
              </tr>
              <tr style="height:10px"></tr>
              <tr>
                <td></td>
                <td>
                  <form method=post action="/r"><input type=hidden name="fnid" value="ejRXtDqiDZRXcoDpWCAK6w"><textarea name="text" rows=6 cols=60></textarea><br><br>
                    <input type=submit value="add comment">
                  </form>
                </td>
              </tr>
            </table>
            <br><br>
            <table border=0>
              <tr>
                <td>
                  <table border=0>
                    <tr>
                      <td><img src="s.gif" height=1 width=0></td>
                      <td valign=top>
                        <center>
                          <a id=up_7012837 onclick="return vote(this)" href="vote?for=7012837&amp;dir=up&amp;by=wting&amp;auth=ee901c3a0f46d05583ff0d3f5303a7e51508d787&amp;whence=%69%74%65%6d%3f%69%64%3d%37%30%31%32%38%33%32">
                            <div class="votearrow" title="upvote"></div>
                          </a>
                          <a id=down_7012837 onclick="return vote(this)" href="vote?for=7012837&amp;dir=down&amp;by=wting&amp;auth=ee901c3a0f46d05583ff0d3f5303a7e51508d787&amp;whence=%69%74%65%6d%3f%69%64%3d%37%30%31%32%38%33%32">
                            <div class="votearrow rotate180" title="downvote"></div>
                          </a>
                        </center>
                      </td>
                      <td class="default">
                        <div style="margin-top:2px; margin-bottom:-10px; "><span class="comhead"><a href="user?id=stesch">stesch</a> 3 minutes ago  | <a href="item?id=7012837">link</a></span></div>
                        <br>
                        <span class="comment"><font color=#000000><a href="https://news.ycombinator.com/item?id=7012753" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=7012753</a> doesn&#x27;t show and there&#x27;s no way&#x2F;link to reach any moderators here.</font></span>
                        <p><font size=1><u><a href="reply?id=7012837&amp;whence=%69%74%65%6d%3f%69%64%3d%37%30%31%32%38%33%32">reply</a></u></font>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
            </table>
            <br><br>
          </td>
        </tr>
        <tr>
          <td>
            <img src="s.gif" height=10 width=0>
            <table width="100%" cellspacing=0 cellpadding=1>
              <tr>
                <td bgcolor=#ff6600></td>
              </tr>
            </table>
            <br>
            <center>
              <span class="yclinks"><a href="lists">Lists</a> | <a href="rss">RSS</a> | <a href="http://ycombinator.com/bookmarklet.html">Bookmarklet</a> | <a href="http://ycombinator.com/newsguidelines.html">Guidelines</a> | <a href="http://ycombinator.com/newsfaq.html">FAQ</a> | <a href="dmca.html">DMCA</a> | <a href="http://ycombinator.com/newsnews.html">News News</a> | <a href="item?id=363">Feature Requests</a> | <a href="https://github.com/HackerNews/HN/issues">Bugs</a> | <a href="http://ycombinator.com">Y Combinator</a> | <a href="http://ycombinator.com/apply.html">Apply</a> | <a href="http://ycombinator.com/lib.html">Library</a></span><br><br>
              <form method=get action="//www.hnsearch.com/search#request/all">Search: <input type=text name="q" value="" size=17></form>
              <br>
            </center>
          </td>
        </tr>
      </table>
    </center>
  </body>
</html>

Null pointer exception in LoginActivity

Stacktrace:

at com.airlocksoftware.hackernews.activity.LoginActivity.doPostAction(LoginActivity.java:177)
at com.airlocksoftware.hackernews.activity.LoginActivity.onLoadFinished(LoginActivity.java:162)
at com.airlocksoftware.hackernews.activity.LoginActivity.onLoadFinished(LoginActivity.java:1)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:425)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:393)
at android.support.v4.content.Loader.deliverResult(Loader.java:103)
at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:221)
at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:61)
at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:461)
at android.support.v4.content.ModernAsyncTask.access$500(ModernAsyncTask.java:47)
at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:474)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.