Android如何解决ANR
程序员文章站
2022-07-14 17:24:00
...
最近小菜要考试了,小菜在大二上学期的时候对安卓做过一些编程,所以对学校开设的这门课也是情有独钟,明天晚上就要考试安卓了,小菜还是淡定的写篇博客压压惊
以前在写小黄鸡音乐播放器的时候,需要在后台获取手机上存储的音乐文件的信息,有时候由于处理不当就会被安卓系统处理提示应用不反应的提示。。。
anr也就是application not response的缩写,站在现在水平看我大二刚接触安卓的时候的水平只能一笑而过,处理耗时操作可以用三种方式来解决:
1,用服务service的方式进行后台操作。
2,在UI线程的基础上开一个子线程来处理耗时操作。
不过这种开子线程的方式有一个问题,就是子线程并不能修改ui(ui线程是主线程)的内容,组建由哪个线程创建,哪个线程才有能力对UI进行修改。
3,用异步处理类来解决这个问题。
现在重点来讨论下第二种和第三种处理方式:
第二种方式可以使用Thread +Handler+Message的方式进行耗时处理并更新界面。
例子如下:
public class MainActivity extends Activity implements OnClickListener
{
private Button bget;
private ImageView imageView;
Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
Bitmap bmp = (Bitmap) msg.obj;
imageView.setImageBitmap(bmp);
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bget = (Button) findViewById(R.id.bget);
imageView = (ImageView) findViewById(R.id.imageview);
bget.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
new Thread()
{
public void run()
{
try
{
URL url = new URL("http://10.0.2.2:9999/testdemo/images/pre4.jpg");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode() ==200)
{
InputStream inputStream = conn.getInputStream();
Bitmap bmp = BitmapFactory.decodeStream(inputStream);
Message message = new Message();
message.obj = bmp;
handler.sendMessage(message);
}
} catch (Exception e)
{
// TODO: handle exception
}
}
}.start();
}
}
第三种方式是使用安卓sdk中带的类AsyncTask,通过继承AsyncTask可以用像ajax的方式来实现异步操作。
public class MainActivity extends Activity implements OnClickListener
{
private Button bget;
private ImageView imageView;
Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
Bitmap bmp = (Bitmap) msg.obj;
imageView.setImageBitmap(bmp);
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bget = (Button) findViewById(R.id.bget);
imageView = (ImageView) findViewById(R.id.imageview);
bget.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute("http://10.0.2.2:9999/testdemo/images/pre4.jpg");
//"http://10.0.2.2:9999/testdemo/images/pre4.jpg"
}
// 第一个参数就是一个字符串,就是网络上的url地址
// 第二个参数是 Integer,标明进度...
// 第三个参数指的是返回的值
class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>
{
// 任务执行前调用的方法,它是在主线程中执行的
@Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values)
{
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
// 后台执行的任务,它是在子线程中...这个的方法的返回参数,会
// 做为onPostExecute()中的传递参数.
@Override
protected Bitmap doInBackground(String... params)
{
// TODO Auto-generated method stub
String urlstr = params[0];
try
{
URL url = new URL(urlstr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode() ==200)
{
InputStream inputStream = conn.getInputStream();
Bitmap bmp = BitmapFactory.decodeStream(inputStream);
return bmp;
}
} catch (Exception e)
{
// TODO: handle exception
}
return null;
}
//任务执行完毕,调用的方法.它也是在主线程中执行的
@Override
protected void onPostExecute(Bitmap result)
{
// TODO Auto-generated method stub
// super.onPostExecute(result);
imageView.setImageBitmap(result);
}
}
}
大概就是这样了,第一种方式有很多例子这里就不在讨论了,待小菜考试结束再来补充
推荐阅读
-
Win10 1803(四月更新版)卡顿怎么解决?Win10 1803如何关闭时间线
-
如何快速解决网站降权问题
-
什么是创业公司中最容易遇到的问题?如何解决这些问题?
-
Mac从睡眠状态开启后连不上WiFi是什么原因如何解决
-
Android WebView或手机浏览器打开连接问题解决办法总结
-
android开发之eclipse adt升级到20.0无法新建android工程解决办法
-
如何解决ORA-01843与NLS_DATE_FORMAT问题
-
如何修改Android Studio创建module时默认的compileSdkVersion
-
Win32/Induc.A是什么病毒该如何解决
-
安装Daemon Tools重启导致蓝屏是什么情况如何解决