Android 中 java.lang.IllegalArgumentException: pointerIndex out of range 异常的处理方法

在记事帐的应用后台收到了一条罕见的崩溃报告:

java.lang.IllegalArgumentException: pointerIndex out of range
at android.view.MotionEvent.nativeGetAxisValue(Native Method)
at android.view.MotionEvent.getX(MotionEvent.java:2189)
at android.support.v4.view.MotionEventCompatEclair.getX(MotionEventCompatEclair.java:32)
at android.support.v4.view.MotionEventCompat$EclairMotionEventVersionImpl.getX(MotionEventCompat.java:86)
at android.support.v4.view.MotionEventCompat.getX(MotionEventCompat.java:184)
at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:1462)
at android.view.View.dispatchTouchEvent(View.java:8149)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2416)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2140)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2295)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1622)
at android.app.Activity.dispatchTouchEvent(Activity.java:2565)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2243)
at android.view.View.dispatchPointerEvent(View.java:8357)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4778)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4644)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4202)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4256)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4225)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4336)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4233)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4393)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4202)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4256)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4225)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4233)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4202)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6569)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6486)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6457)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6422)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6649)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:138)
at android.os.Looper.loop(Looper.java:131)
at android.app.ActivityThread.main(ActivityThread.java:5602)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)

经调查,发现这是 Android 的 ViewPager 的一个 bug,偶尔会在用户执行多点触控操作时发生。直到至少 Android 4.4,该问题依然存在。
解决方案也很简单,覆写 ViewPager 的 onTouchEvent 与 onInterceptTouchEvent 方法,catch 该异常即可,如下所示:

@Override
    public boolean onTouchEvent(MotionEvent me) {
        try {
            return super.onTouchEvent(me);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
        return false;
    }

Android 应用 蓝色光波过滤器(BlueLight Filter)版本升级 1.922

小规模升级,修复了一些细节问题。

最重要的是,蓝色光波过滤器在 Google Play 商店的全球下载量突破了10,000,000次(其中中文用户达3,500,000)。这是一个里程碑,也是新的起点。

下载次数超过10,000,000

 

另一个相对小众的「记事帐」应用也于近日超过了200,000次下载,计划近期发布更新,敬请期待。

 

可以从这里跳转至 Google Play 页面进行下载。

.NET 开发笔记

作为分类目录的一个补充,在这里按照功能类别对 .NET 开发中的一点心得和笔记作一个索引。其中部分是根据自己在查找网络资料时找到的内容的整理与演绎,在此感谢所有那些无私分享经验的人们。

Entity Framework

Web

.NET 中 Entity Framework 的数据库查询

Entity Framework 支持三种类型的数据库查询。

  • LINQ to Entities
  • Entity SQL
  • Native SQL

其中,LINQ(音:link)是较为推荐的方式。它又分为 LINQ Method syntax 与 LINQ Query syntax,如下所示。

// LINQ Method syntax
using (var context = new CompanyDBEntities()) 
{ 
    var L2EQuery = context.Employees.where(e => e.EmployeeName== "Ben"); 
    var employee= L2EQuery.FirstOrDefault(); 
} 

// LINQ Query syntax
using (var context = new CompanyDBEntities()) 
{ 
    var L2EQuery = from ep in context.Employees    
                   where ep.EmployeeName == "Bill" 
                   select ep; 
     var employee = L2EQuery.FirstOrDefault(); 
} 

Entity SQL 与 Native SQL 都是基于拼接 SQL 语句的方式,如下所示。

// Entity SQL
string sqlString = "SELECT VALUE ep FROM CompanyDBEntities.Employees " + "AS ep WHERE ep.EmployeeName == 'Ben'"; 
var objctx = (ctx as IObjectContextAdapter).ObjectContext; 
ObjectQuery employee = objctx.CreateQuery(sqlString); 
Employee newEmployee = employee.First(); 

// Native SQL
using (var ctx = new CompanyDBEntities()) 
{ 
    var employeeName = ctx.Employees.SqlQuery("Select EmployeeId, EmployeeName from Employee where EmployeeName='Ben'").FirstOrDefault(); 
} 

此外,Entity Framework 提供了丰富的函数,应了解并掌握用法。以下列举一些。

  • Aggregate*
  • Average
  • All
  • Any
  • ElementAt/ElementAtOrDefault*
  • Single/SingleOrDefault*
  • Contains
  • First/FirstOrDefault/Last/LastOrDefault*
  • Count
  • Max/Min*
  • OrderBy/OrderByDescending
  • Reverse
  • SelectMany
  • SequenceEqual
  • Skip/SkipWhile
  • Take/TakeWhile

其中以星号标记的将返回 Entity 实体。

Android 应用 蓝色光波过滤器(BlueLight Filter)版本升级 1.921

近日,蓝色光波过滤器升级到了 1.921,除了例行的稳定性提升,还特别加入了夜间模式支持。

夜间模式简言之,可以将屏幕亮度限制至极低的程度,确保用户在夜间无光环境下也能长时间观看手机而不会因刺眼光线感到眼睛疲劳。

夜间模式的灵感源于 Google Play Books 的夜间阅读模式,但提供了更为细致的级别选项,并能作用于设备全局。

可以从这里跳转至 Google Play 页面进行下载。