全部产品
云市场

java_lang_IllegalArgumentException

更新时间:2018-04-19 17:19:38

问题分析:

根据Android官方文档,当方法接收到了一个不合法或不正确的参数时会抛出此类异常。

解决方案:

因为参数不合法导致抛出IllegalArgumentException,请根据堆栈信息描述的出错的函数参数,按照要求传入正确的参数。

代码示例:

  1. public static void getUserAgent(Context context) {
  2. WebView webview = new WebView(context);
  3. WebSettings settings = webview.getSettings();
  4. userAgent = settings.getUserAgentString();
  5. Log.i("UserAgent:" + userAgent);
  6. }

示例一:

  1. java.lang.IllegalArgumentException: HTTP parameters may not be null
  2. at org.apache.http.params.HttpProtocolParams.getUserAgent(HttpProtocolParams.java:150)
  3. at org.apache.http.impl.client.AbstractHttpClient.isMoMMS(AbstractHttpClient.java:790)
  4. at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:563)
  5. at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:520)
  6. at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:498)
  7. at com.g.utils.HttpClientUtil.post(HttpClientUtil.java:99)
  8. at com.g.utils.LoadDataFromServer$2.run(LoadDataFromServer.java:195)

因为参数为空导致获取字符集失败抛出的异常。

在这个例子里,getUserAgent因为userAgent变量为空所以报错。User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。

示例二:

  1. java.lang.IllegalArgumentException
  2. at android.view.Surface.nativeLockCanvas(Native Method)
  3. at android.view.Surface.lockCanvas(Surface.java:243)
  4. at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2435)
  5. at android.view.ViewRootImpl.draw(ViewRootImpl.java:2409)
  6. at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2253)
  7. at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1883)
  8. at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
  9. at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
  10. at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
  11. at android.view.Choreographer.doCallbacks(Choreographer.java:574)
  12. at android.view.Choreographer.doFrame(Choreographer.java:544)
  13. at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
  14. at android.os.Handler.handleCallback(Handler.java:733)
  15. at android.os.Handler.dispatchMessage(Handler.java:95)
  16. at android.os.Looper.loop(Looper.java:136)
  17. at android.app.ActivityThread.main(ActivityThread.java:5017)
  18. at java.lang.reflect.Method.invokeNative(Native Method)
  19. at java.lang.reflect.Method.invoke(Method.java:515)
  20. at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
  21. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
  22. at dalvik.system.NativeStart.main(Native Method)

问题分析:

该问题在Android诸多系统版本均有出现。这个问题是由于Android系统的bug导致Webview内存无法被正确管理,从而导致内存泄漏。当内存太低时,绘图时无法申请到内存资源,导致此异常抛出,应用崩溃。

解决方案:

A.强制管理Webview的生命周期。在Webview对应的Activity的声明周期管理中,对webview进行强制的管理。当Activity在onPause()时,强制destory掉webview,并清空webview的container。这样,webview占用的内存会在下一次GC时,被系统回收。

  1. @Override
  2. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
  3. View v = super.onCreateView(inflater, container, saved);
  4. mActivity = (BaseActivity) getSupportActivity();
  5. // this is the framelayout which will contain our WebView
  6. mWebContainer = (FrameLayout) v.findViewById(R.id.web_container);
  7. return v;
  8. }
  9. public void onResume() {
  10. super.onResume();
  11. // create new WebView and set all its options.
  12. mWebView = new WebView(mActivity);
  13. mWebView....
  14. // add it to the container
  15. mWebContainer.addView(mWebView);
  16. // if data is available, display it immediately
  17. if(mTopic != null) {
  18. mWebView.loadDataWithBaseURL("file:///android_asset/", mTopic.getHtmlCache(),
  19. "text/html", "UTF-8", null);
  20. }
  21. }
  22. @Override
  23. public void onPause() {
  24. super.onPause();
  25. // destroy the webview
  26. mWebView.destroy();
  27. mWebView = null;
  28. // remove the view from the container.
  29. mWebContainer.removeAllViews();
  30. }

B.取消应用的硬件加速

在AndroidManifest.xml里增加android:hardwareAccelerated=”false”,用来禁止硬件加速,此方法可以避免该系统bug。不过,不推荐游戏或者对流畅性要求很高的应用采用此方法,可能会导致应用变得有一些卡顿。

示例三:

  1. 01-17 00:19:44.703: E/Surface(9731): Surface::lock failed, already locked
  2. 01-17 00:19:44.796: E/SurfaceHolder(9731): Exception locking surface
  3. 01-17 00:19:44.796: E/SurfaceHolder(9731): java.lang.IllegalArgumentException
  4. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.Surface.lockCanvasNative(Native Method)
  5. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.Surface.lockCanvas(Surface.java:314)
  6. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:762)
  7. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:741)
  8. 01-17 00:19:44.796: E/SurfaceHolder(9731): at com.frequency.FreqTapArea$2.onTouch(FreqTapArea.java:54)
  9. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.View.dispatchTouchEvent(View.java:3897)
  10. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
  11. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
  12. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
  13. 01-17 00:19:44.796: E/SurfaceHolder(9731): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1737)
  14. 01-17 00:19:44.796: E/SurfaceHolder(9731): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1153)
  15. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
  16. 01-17 00:19:44.796: E/SurfaceHolder(9731): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1721)
  17. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2200)
  18. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.view.ViewRoot.handleMessage(ViewRoot.java:1884)
  19. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.os.Handler.dispatchMessage(Handler.java:99)
  20. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.os.Looper.loop(Looper.java:130)
  21. 01-17 00:19:44.796: E/SurfaceHolder(9731): at android.app.ActivityThread.main(ActivityThread.java:3835)
  22. 01-17 00:19:44.796: E/SurfaceHolder(9731): at java.lang.reflect.Method.invokeNative(Native Method)
  23. 01-17 00:19:44.796: E/SurfaceHolder(9731): at java.lang.reflect.Method.invoke(Method.java:507)
  24. 01-17 00:19:44.796: E/SurfaceHolder(9731): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
  25. 01-17 00:19:44.796: E/SurfaceHolder(9731): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
  26. 01-17 00:19:44.796: E/SurfaceHolder(9731): at dalvik.system.NativeStart.main(Native Method))

问题分析:

Canvas在操作之前需要加锁(lockCanvas函数),操作结束后,应该立即释放锁资源(unlockCanvasAndPost函数),这个问题的出现就是因为lockCanvas()之后没有释放锁资源,正确的流程是:

A.调用 mSurfaceHolder.lockCanvas(); 获取Canvas对象。

B.调用Canvas方法进行绘图:canvas.drawXXX(arg, arg, arg, arg);

C.绘图完成之后,调用 mSurfaceHolder.unlockCanvasAndPost(c); 释放锁资源。

代码示例:

  1. public boolean draw(View arg0, MotionEvent arg1) {
  2. Canvas c = mSurfaceHolder.lockCanvas();
  3. // Draw something
  4. c.drawCircle(args,…,arg);
  5. mSurfaceHolder.unlockCanvasAndPost(c);
  6. return true;
  7. }

参考文章:

1.https://developer.android.com/reference/java/lang/IllegalArgumentException.html

2.http://stackoverflow.com/questions/20554621/after-a-while-of-usage-my-app-freezes-during-scrolling-a-webview-saying-could

3.http://stackoverflow.com/questions/8875702/android-canvas-locking-throws-illegalargumentexceptionhttp://androidxref.com/4.4_r1/xref/external/apache-http/src/org/apache/http/params/HttpProtocolParams.java#148