为什么使用Try,Catchtry catch 捕获不了异常,程序依然Crash

当前访客身份:游客 [
这个人很懒,啥也没写
:建议代码放在osc git上
:哥们你把搜索功能干掉了!
:楼主,加油,经典好文,请继续分析
:引用来自“hz_bill_shou”的评论 下载链接打不开...
:引用来自“阎魔爱”的评论 楼主啊~~请教个问题呗...
:楼主啊~~请教个问题呗。我刚开始接触android 能介...
:下载链接打不开哇
:建议放到SVN,大家一起来改造,比如http://code...
:不错不错!
今日访问:0
昨日访问:10
本周访问:23
本月访问:35
所有访问:5896
[开源中国]android客户端-异常捕获
发表于2年前( 19:56)&&
阅读(1728)&|&评论()
0人收藏此文章,
开源中国的异常捕获的处理类在AppException.java中,产生的堆栈信息不是太详细,尤其是没有到底是在哪行出错的。这样对于查看修改bug还是增加了工作量,这里对异常的堆栈信息修改了一下,经过实际测试,能够正确的显示是哪个类,哪行出的问题。
关键的代码是:
& public static StringBuffer getTraceInfo(Activity a, Throwable e) { &&& StringBuffer sb = new StringBuffer(); &&& StackTraceElement[] stacks = e.getCause().getStackTrace(); &&& for (int i = 0; i & stacks. i++) { &&&&& if (stacks[i].getClassName().contains(a.getLocalClassName())) { &&&&&&& sb.append("class: ").append(stacks[i].getClassName()).append("; method: ") &&&&&&&&&&& .append(stacks[i].getMethodName()).append("; line: ").append(stacks[i].getLineNumber()) &&&&&&&&&&& .append(";& Exception: ").append(e.getCause().toString()); &&&&&&& &&&&& } &&& } &&& & }
完整的类内容如下:
package com.childapp.
import java.io.F import java.io.FileW import java.io.IOE import java.io.PrintW import java.lang.Thread.UncaughtExceptionH import java.lang.reflect.F import java.net.ConnectE import java.net.SocketE import java.net.UnknownHostE import java.util.D
import mons.httpclient.HttpE import org.json.JSONE import org.json.JSONO
import android.app.A import android.content.C import android.content.pm.PackageI import android.content.pm.PackageM import android.content.pm.PackageManager.NameNotFoundE import android.os.B import android.os.E import android.os.L import android.text.format.DateF import android.util.L import android.widget.T
import com.childapp.R; import mon.AppA import mon.AppM import mon.GlobalC import com.childapp.utils.UIH
/** &* 应用程序异常类:用于捕获异常和提示错误信息 &*
liux () &*
&*/ public class AppException extends Exception implements UncaughtExceptionHandler {
& /** && *
&& */ & private static final long serialVersionUID = 1877535L;
& private final static boolean Debug =// 是否保存错误日志
& /** 定义异常类型 */ & public final static byte TYPE_NETWORK = 0x01; & public final static byte TYPE_SOCKET = 0x02; & public final static byte TYPE_HTTP_CODE = 0x03; & public final static byte TYPE_HTTP_ERROR = 0x04; & public final static byte TYPE_XML = 0x05; & public final static byte TYPE_IO = 0x06; & public final static byte TYPE_RUN = 0x07;
& /** 系统默认的UncaughtException处理类 */ & private Thread.UncaughtExceptionHandler mDefaultH
& private AppException() { &&& this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); & }
& private AppException(byte type, int code, Exception excp) { &&& super(excp); &&& this.type = &&& this.code = &&& if (Debug) { &&&&& this.saveErrorLog(excp); &&& } & }
& public int getCode() { &&& return this. & }
& public int getType() { &&& return this. & }
& /** && * 提示友好的错误信息 && *
&& * @param ctx && */ & public void makeToast(Context ctx) { &&& switch (this.getType()) { &&&&& case TYPE_HTTP_CODE: &&&&&&& String err = ctx.getString(R.string.http_status_code_error, this.getCode()); &&&&&&& Toast.makeText(ctx, err, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_HTTP_ERROR: &&&&&&& Toast.makeText(ctx, R.string.http_exception_error, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_SOCKET: &&&&&&& Toast.makeText(ctx, R.string.socket_exception_error, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_NETWORK: &&&&&&& Toast.makeText(ctx, R.string.network_not_connected, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_XML: &&&&&&& Toast.makeText(ctx, R.string.xml_parser_failed, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_IO: &&&&&&& Toast.makeText(ctx, R.string.io_exception_error, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_RUN: &&&&&&& Toast.makeText(ctx, R.string.app_run_code_error, Toast.LENGTH_SHORT).show(); &&&&&&& &&& } & }
& /** && * 保存异常日志 && *
&& * @param excp && */ & public void saveErrorLog(Exception excp) { &&& saveErrorLog(excp.getLocalizedMessage()); & }
& /** && * 保存异常日志 && *
&& * @param excp && */ & public void saveErrorLog(String excpMessage) { &&& String errorlog = "errorlog.txt"; &&& String savePath = ""; &&& String logFilePath = ""; &&& FileWriter fw = &&& PrintWriter pw = &&& try { &&&&& // 判断是否挂载了SD卡 &&&&& String storageState = Environment.getExternalStorageState(); &&&&& if (storageState.equals(Environment.MEDIA_MOUNTED)) { &&&&&&& savePath = &&&&&&&&&&& Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator &&&&&&&&&&&&&&& + GlobalConstants.FOLDER_ROOT + File.separator + "Log/"; &&&&&&& File file = new File(savePath); &&&&&&& if (!file.exists()) { &&&&&&&&& file.mkdirs(); &&&&&&& } &&&&&&& logFilePath = savePath + &&&&& } &&&&& // 没有挂载SD卡,无法写文件 &&&&& if (logFilePath == "") { &&&&&&& &&&&& } &&&&& File logFile = new File(logFilePath); &&&&& if (!logFile.exists()) { &&&&&&& logFile.createNewFile(); &&&&& } &&&&& fw = new FileWriter(logFile, true); &&&&& pw = new PrintWriter(fw); &&&&& pw.println("--------------------" + (DateFormat.format("yyyy-MM-dd hh:mm:ss", new Date())) &&&&&&&&& + "---------------------"); &&&&& pw.println(excpMessage); &&&&& pw.close(); &&&&& fw.close(); &&& } catch (Exception e) { &&&&& Log.e("AppException", "[Exception]" + e.getLocalizedMessage()); &&& } finally { &&&&& if (pw != null) { &&&&&&& pw.close(); &&&&& } &&&&& if (fw != null) { &&&&&&& try { &&&&&&&&& fw.close(); &&&&&&& } catch (IOException e) {} &&&&& } &&& }
& public static AppException http(int code) { &&& return new AppException(TYPE_HTTP_CODE, code, null); & }
& public static AppException http(Exception e) { &&& return new AppException(TYPE_HTTP_ERROR, 0, e); & }
& public static AppException socket(Exception e) { &&& return new AppException(TYPE_SOCKET, 0, e); & }
& public static AppException io(Exception e) { &&& if (e instanceof UnknownHostException || e instanceof ConnectException) { &&&&& return new AppException(TYPE_NETWORK, 0, e); &&& } else if (e instanceof IOException) { &&&&& return new AppException(TYPE_IO, 0, e); &&& } &&& return run(e); & }
& public static AppException xml(Exception e) { &&& return new AppException(TYPE_XML, 0, e); & }
& public static AppException network(Exception e) { &&& if (e instanceof UnknownHostException || e instanceof ConnectException) { &&&&& return new AppException(TYPE_NETWORK, 0, e); &&& } else if (e instanceof HttpException) { &&&&& return http(e); &&& } else if (e instanceof SocketException) { &&&&& return socket(e); &&& } &&& return http(e); & }
& public static AppException run(Exception e) { &&& return new AppException(TYPE_RUN, 0, e); & }
& /** && * 获取APP异常崩溃处理对象 && *
&& * @param context && *
&& */ & public static AppException getAppExceptionHandler() { &&& return new AppException(); & }
& @Override & public void uncaughtException(Thread thread, Throwable ex) {
&&& if (!handleException(ex) && mDefaultHandler != null) { &&&&& mDefaultHandler.uncaughtException(thread, ex); &&& } else { &&&&& try { &&&&&&& Thread.sleep(15000); &&&&& } catch (InterruptedException e) { &&&&&&& Log.e("AppException", "error : ", e); &&&&& } &&&&& // 退出程序 &&&&& android.os.Process.killProcess(android.os.Process.myPid()); &&&&& System.exit(1); &&& }
& /** && * 自定义异常处理:收集错误信息&发送错误报告 && *
&& * @param ex && *
true:处理了该异常信息;否则返回false && */ & private boolean handleException(Throwable ex) { &&& if (ex == null) { &&&&& &&& }
&&& final Context context = AppManager.getAppManager().currentActivity();
&&& if (context == null) { &&&&& &&& }
&&& final String crashReport = getCrashReport(context, ex); &&& // 显示异常信息&发送报告 &&& new Thread() { &&&&& public void run() { &&&&&&& Looper.prepare(); &&&&&&& UIHelper.sendAppCrashReport(context, crashReport); &&&&&&& Looper.loop(); &&&&& }
&&& }.start();
&&& saveErrorLog(crashReport);
& /** && * 获取APP崩溃异常报告 && *
&& * @param ex && *
&& */ & private String getCrashReport(Context context, Throwable ex) { &&& PackageInfo pinfo = ((AppApplication) context.getApplicationContext()).getPackageInfo(); &&& StringBuffer exceptionStr = new StringBuffer(); &&& exceptionStr.append("Version: " + pinfo.versionName + "(" + pinfo.versionCode + ")\n"); &&& exceptionStr.append("Android: " + android.os.Build.VERSION.RELEASE + "(" &&&&&&& + android.os.Build.MODEL + ")\n"); &&& exceptionStr.append("System package Info:" + collectDeviceInfo(context) + "\n"); &&& exceptionStr.append("System os Info:" + getMobileInfo() + "\n"); &&& exceptionStr.append("Exception: " + ex.getMessage() + "\n"); &&& exceptionStr.append("Exception stack:" + getTraceInfo((Activity) context, ex) + "\n"); &&& StackTraceElement[] elements = ex.getStackTrace(); &&& for (int i = 0; i & elements. i++) { &&&&& exceptionStr.append(elements[i].toString() + "\n"); &&& } &&& return exceptionStr.toString(); & }
& /** && * 收集设备参数信息 && *
&& * @param ctx && */ & public String collectDeviceInfo(Context ctx) { &&& StringBuilder sb = new StringBuilder(); &&& JSONObject activePackageJson = new JSONObject();
&&& try { &&&&& PackageManager pm = ctx.getPackageManager(); &&&&& PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); &&&&& if (pi != null) { &&&&&&& String versionName = pi.versionName == null ? "null" : pi.versionN &&&&&&& String versionCode = pi.versionCode + "";
&&&&&&& activePackageJson.put("versionName", versionName); &&&&&&& activePackageJson.put("versionCode", versionCode); &&&&& } &&& } catch (NameNotFoundException e) { &&&&& Log.e("AppException", "an error occured when collect package info", e); &&& } catch (JSONException e) { &&&&& Log.e("AppException", "jsonException", e); &&& } &&& sb.append("[active Package]"); &&& sb.append(activePackageJson.toString());
&&& return sb.toString(); & }
& public static StringBuffer getTraceInfo(Activity a, Throwable e) { &&& StringBuffer sb = new StringBuffer(); &&& StackTraceElement[] stacks = e.getCause().getStackTrace(); &&& for (int i = 0; i & stacks. i++) { &&&&& if (stacks[i].getClassName().contains(a.getLocalClassName())) { &&&&&&& sb.append("class: ").append(stacks[i].getClassName()).append("; method: ") &&&&&&&&&&& .append(stacks[i].getMethodName()).append("; line: ").append(stacks[i].getLineNumber()) &&&&&&&&&&& .append(";& Exception: ").append(e.getCause().toString()); &&&&&&& &&&&& } &&& } &&& & }
& /** && * 获取手机的硬件信息 && *
&& */ & public String getMobileInfo() { &&& JSONObject osJson = new JSONObject(); &&& // 通过反射获取系统的硬件信息
&&& Field[] fields = Build.class.getDeclaredFields(); &&& for (Field field : fields) { &&&&& try { &&&&&&& field.setAccessible(true); &&&&&&& osJson.put(field.getName(), field.get(null).toString()); &&&&&&& Log.d("AppException", field.getName() + " : " + field.get(null)); &&&&& } catch (Exception e) { &&&&&&& Log.e("AppException", "an error occured when collect crash info", e); &&&&& } &&& }
&&& return osJson.toString(); & }
时隔多日,发现上面的还是有些问题,进行了再次的优化,堆栈信息打的更加好了。代码如下:
import java.io.F import java.io.FileW import java.io.IOE import java.io.PrintW import java.lang.Thread.UncaughtExceptionH import java.lang.reflect.F import java.net.ConnectE import java.net.SocketE import java.net.UnknownHostE import java.util.D
import mons.httpclient.HttpE import org.json.JSONE import org.json.JSONO
import android.app.A import android.content.C import android.content.pm.PackageI import android.content.pm.PackageM import android.content.pm.PackageManager.NameNotFoundE import android.os.B import android.os.E import android.os.L import android.text.format.DateF import android.util.L import android.widget.T
import com.childapp.R; import mon.AppA import mon.AppM import mon.GlobalC import com.childapp.utils.UIH
/** &* 应用程序异常类:用于捕获异常和提示错误信息 &*
&* @author liux () &* @version 1.0 &* @created
&*/ public class AppException extends Exception implements UncaughtExceptionHandler {
& /** && *
&& */ & private static final long serialVersionUID = 1877535L;
& private final static boolean Debug =// 是否保存错误日志
& /** 定义异常类型 */ & public final static byte TYPE_NETWORK = 0x01; & public final static byte TYPE_SOCKET = 0x02; & public final static byte TYPE_HTTP_CODE = 0x03; & public final static byte TYPE_HTTP_ERROR = 0x04; & public final static byte TYPE_XML = 0x05; & public final static byte TYPE_IO = 0x06; & public final static byte TYPE_RUN = 0x07;
& /** 系统默认的UncaughtException处理类 */ & private Thread.UncaughtExceptionHandler mDefaultH
& private AppException() { &&& this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); & }
& private AppException(byte type, int code, Exception excp) { &&& super(excp); &&& this.type = &&& this.code = &&& if (Debug) { &&&&& this.saveErrorLog(excp); &&& } & }
& public int getCode() { &&& return this. & }
& public int getType() { &&& return this. & }
& /** && * 提示友好的错误信息 && *
&& * @param ctx && */ & public void makeToast(Context ctx) { &&& switch (this.getType()) { &&&&& case TYPE_HTTP_CODE: &&&&&&& String err = ctx.getString(R.string.http_status_code_error, this.getCode()); &&&&&&& Toast.makeText(ctx, err, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_HTTP_ERROR: &&&&&&& Toast.makeText(ctx, R.string.http_exception_error, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_SOCKET: &&&&&&& Toast.makeText(ctx, R.string.socket_exception_error, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_NETWORK: &&&&&&& Toast.makeText(ctx, R.string.network_not_connected, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_XML: &&&&&&& Toast.makeText(ctx, R.string.xml_parser_failed, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_IO: &&&&&&& Toast.makeText(ctx, R.string.io_exception_error, Toast.LENGTH_SHORT).show(); &&&&&&& &&&&& case TYPE_RUN: &&&&&&& Toast.makeText(ctx, R.string.app_run_code_error, Toast.LENGTH_SHORT).show(); &&&&&&& &&& } & }
& /** && * 保存异常日志 && *
&& * @param excp && */ & public void saveErrorLog(Exception excp) { &&& saveErrorLog(excp.getLocalizedMessage()); & }
& /** && * 保存异常日志 && *
&& * @param excp && */ & public void saveErrorLog(String excpMessage) { &&& String errorlog = "errorlog.txt"; &&& String savePath = ""; &&& String logFilePath = ""; &&& FileWriter fw = &&& PrintWriter pw = &&& try { &&&&& // 判断是否挂载了SD卡 &&&&& String storageState = Environment.getExternalStorageState(); &&&&& if (storageState.equals(Environment.MEDIA_MOUNTED)) { &&&&&&& savePath = &&&&&&&&&&& Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator &&&&&&&&&&&&&&& + GlobalConstants.FOLDER_ROOT + File.separator + "Log/"; &&&&&&& File file = new File(savePath); &&&&&&& if (!file.exists()) { &&&&&&&&& file.mkdirs(); &&&&&&& } &&&&&&& logFilePath = savePath + &&&&& } &&&&& // 没有挂载SD卡,无法写文件 &&&&& if (logFilePath == "") { &&&&&&& &&&&& } &&&&& File logFile = new File(logFilePath); &&&&& if (!logFile.exists()) { &&&&&&& logFile.createNewFile(); &&&&& } &&&&& fw = new FileWriter(logFile, true); &&&&& pw = new PrintWriter(fw); &&&&& pw.println("--------------------" + (DateFormat.format("yyyy-MM-dd hh:mm:ss", new Date())) &&&&&&&&& + "---------------------"); &&&&& pw.println(excpMessage); &&&&& pw.close(); &&&&& fw.close(); &&& } catch (Exception e) { &&&&& Log.e("AppException", "[Exception]" + e.getLocalizedMessage()); &&& } finally { &&&&& if (pw != null) { &&&&&&& pw.close(); &&&&& } &&&&& if (fw != null) { &&&&&&& try { &&&&&&&&& fw.close(); &&&&&&& } catch (IOException e) {} &&&&& } &&& }
& public static AppException http(int code) { &&& return new AppException(TYPE_HTTP_CODE, code, null); & }
& public static AppException http(Exception e) { &&& return new AppException(TYPE_HTTP_ERROR, 0, e); & }
& public static AppException socket(Exception e) { &&& return new AppException(TYPE_SOCKET, 0, e); & }
& public static AppException io(Exception e) { &&& if (e instanceof UnknownHostException || e instanceof ConnectException) { &&&&& return new AppException(TYPE_NETWORK, 0, e); &&& } else if (e instanceof IOException) { &&&&& return new AppException(TYPE_IO, 0, e); &&& } &&& return run(e); & }
& public static AppException xml(Exception e) { &&& return new AppException(TYPE_XML, 0, e); & }
& public static AppException network(Exception e) { &&& if (e instanceof UnknownHostException || e instanceof ConnectException) { &&&&& return new AppException(TYPE_NETWORK, 0, e); &&& } else if (e instanceof HttpException) { &&&&& return http(e); &&& } else if (e instanceof SocketException) { &&&&& return socket(e); &&& } &&& return http(e); & }
& public static AppException run(Exception e) { &&& return new AppException(TYPE_RUN, 0, e); & }
& /** && * 获取APP异常崩溃处理对象 && *
&& * @param context && * @return && */ & public static AppException getAppExceptionHandler() { &&& return new AppException(); & }
& @Override & public void uncaughtException(Thread thread, Throwable ex) {
&&& if (!handleException(ex) && mDefaultHandler != null) { &&&&& mDefaultHandler.uncaughtException(thread, ex); &&& } else { &&&&& try { &&&&&&& Thread.sleep(15000); &&&&& } catch (InterruptedException e) { &&&&&&& Log.e("AppException", "error : ", e); &&&&& } &&&&& // 退出程序 &&&&& android.os.Process.killProcess(android.os.Process.myPid()); &&&&& System.exit(1); &&& }
& /** && * 自定义异常处理:收集错误信息&发送错误报告 && *
&& * @param ex && * @return true:处理了该异常信息;否则返回false && */ & private boolean handleException(Throwable ex) { &&& if (ex == null) { &&&&& &&& }
&&& final Context context = AppManager.getAppManager().currentActivity();
&&& if (context == null) { &&&&& &&& }
&&& final String crashReport = getCrashReport(context, ex); &&& // 显示异常信息&发送报告 &&& new Thread() { &&&&& public void run() { &&&&&&& Looper.prepare(); &&&&&&& UIHelper.sendAppCrashReport(context, crashReport); &&&&&&& Looper.loop(); &&&&& }
&&& }.start();
&&& saveErrorLog(crashReport);
& /** && * 获取APP崩溃异常报告 && *
&& * @param ex && * @return && */ & private String getCrashReport(Context context, Throwable ex) { &&& PackageInfo pinfo = ((AppApplication) context.getApplicationContext()).getPackageInfo(); &&& StringBuffer exceptionStr = new StringBuffer(); &&& exceptionStr.append("Version: " + pinfo.versionName + "(" + pinfo.versionCode + ")\n"); &&& exceptionStr.append("Android: " + android.os.Build.VERSION.RELEASE + "(" &&&&&&& + android.os.Build.MODEL + ")\n"); &&& exceptionStr.append("System package Info:" + collectDeviceInfo(context) + "\n"); &&& exceptionStr.append("System os Info:" + getMobileInfo() + "\n"); &&& exceptionStr.append("Exception: " + ex.getMessage() + "\n"); &&& exceptionStr.append("Exception stack:" + getTraceInfo((Activity) context, ex) + "\n");
&&& return exceptionStr.toString(); & }
& /** && * 收集设备参数信息 && *
&& * @param ctx && */ & public String collectDeviceInfo(Context ctx) { &&& StringBuilder sb = new StringBuilder(); &&& JSONObject activePackageJson = new JSONObject();
&&& try { &&&&& PackageManager pm = ctx.getPackageManager(); &&&&& PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); &&&&& if (pi != null) { &&&&&&& String versionName = pi.versionName == null ? "null" : pi.versionN &&&&&&& String versionCode = pi.versionCode + "";
&&&&&&& activePackageJson.put("versionName", versionName); &&&&&&& activePackageJson.put("versionCode", versionCode); &&&&& } &&& } catch (NameNotFoundException e) { &&&&& Log.e("AppException", "an error occured when collect package info", e); &&& } catch (JSONException e) { &&&&& Log.e("AppException", "jsonException", e); &&& } &&& sb.append("[active Package]"); &&& sb.append(activePackageJson.toString());
&&& return sb.toString(); & }
& public static StringBuffer getTraceInfo(Activity a, Throwable e) { &&& StringBuffer sb = new StringBuffer();
&&& Throwable ex = e.getCause() == null ? e : e.getCause(); &&& StackTraceElement[] stacks = ex.getStackTrace(); &&& for (int i = 0; i & stacks. i++) { &&&&& sb.append("class: ").append(stacks[i].getClassName()).append("; method: ") &&&&&&&&& .append(stacks[i].getMethodName()).append("; line: ").append(stacks[i].getLineNumber()) &&&&&&&&& .append(";& Exception: ").append(ex.toString() + "\n"); &&& } &&& & }
& /** && * 获取手机的硬件信息 && *
&& * @return && */ & public String getMobileInfo() { &&& JSONObject osJson = new JSONObject(); &&& // 通过反射获取系统的硬件信息
&&& Field[] fields = Build.class.getDeclaredFields(); &&& for (Field field : fields) { &&&&& try { &&&&&&& field.setAccessible(true); &&&&&&& osJson.put(field.getName(), field.get(null).toString()); &&&&&&& Log.d("AppException", field.getName() + " : " + field.get(null)); &&&&& } catch (Exception e) { &&&&&&& Log.e("AppException", "an error occured when collect crash info", e); &&&&& } &&& }
&&& return osJson.toString(); & }
更多开发者职位上
1)">1)">1" ng-class="{current:{{currentPage==page}}}" ng-repeat="page in pages"><li class='page' ng-if="(endIndex<li class='page next' ng-if="(currentPage
相关文章阅读}

我要回帖

更多关于 try catch 抛出异常 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信