展会信息港展会大全

Android基本概念 什么是ANR 如何避免它?
来源:互联网   发布日期:2016-01-19 12:04:59   浏览:4125次  

导读:android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电 脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用安卓或安致。什么是AN ...

android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电 脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 安卓 或 安致 。

什么是ANR 如何避免它?

ANR:Application Not Responding。

在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。当出现下列情况时,Android就会显示ANR对话框了:

用户对应用程序的操作(如输入事件,按键、触摸屏事件)在5秒内无响应

广播接受器(BroadcastReceiver)在10秒内仍未执行完毕

Android应用程序完全运行在一个独立的线程中(例如main)。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR。 因为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intent broadcast)。

避免方法:Activity应该在它的关键生命周期方法(如 onCreate()和onResume())里尽可能少的去做创建操作,

潜在的耗时操作。例如网络或数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者异步方式)来完成。

主线程应该为子线程提供一个Handler,以便完成时能够提交给主线程。

Android Intent的使用

(转自http://blog.csdn.net/superjunjin/article/details/7855995)

在一个Android应用中,主要是由一些组件组成,(Activity,Service,ContentProvider,etc.)在这些组件 之间的通讯中,由Intent协助完成。

正如网上一些人解析所说,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述, 负责找 到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent在这里起着实现调用者与被调用者之间的解耦作用。

Intent传递过程中,要找到目标消费者(另一个Activity,IntentReceiver或Service),也就是Intent的响应者,有 两种方法来匹配:

1、显示匹配(Explicit):

public TestB extents Activity

{

.........

};

public class Test extends Activity

{

......

public void switchActivity()

{

Intent i = new Intent(Test.this, TestB.class);

this.startActivity(i);

}

}

代码简洁明了,执行了switchActivity()函数,就会马上跳转到名为TestB的Activity中。

2、隐式匹配(Implicit):

隐式匹配,首先要匹配Intent的几项值:Action, Category, Data/Type,Component

如果填写了Componet就是上例中的Test.class)这就形成了显示匹配。所以此部分只讲前几种匹配。匹配规则为最大匹配规则,

1、如果你填写了Action,如果有一个程序的Manifest.xml中的某一个Activity的 IntentFilter段中定义了包含了相同的Action那么这个Intent就与这个目标Action匹配,如果这个Filter段中没有定义 Type,Category,那么这个Activity就匹配了。但是如果手机中有两个以上的程序匹配,那么就会弹出一个对话可框来提示说明。

Action 的值在Android中有很多预定义,如果你想直接转到你自己定义的Intent接收者,你可以在接收者的IntentFilter中加入一个自定义的 Action值(同时要设定Category值为"android.intent.category.DEFAULT"),在你的Intent中设定该值 为Intent的Action,就直接能跳转到你自己的Intent接收者中。因为这个Action在系统中是唯一的。

2、data/type,你可以用Uri来做为data,比如Uri uri = Uri.parse(http://www.google.com );

Intent i = new Intent(Intent.ACTION_VIEW,uri);手机的Intent分发过程中,会根据http://www.google.com 的scheme判断出数据类型 type

手机的Brower则能匹配它,在Brower的Manifest.xml中的IntenFilter中首先有ACTION_VIEW Action,也 能处理http:的type,

3、至于分类Category,一般不要去在Intent中设置它, 如果你写Intent的接收者,就在Manifest.xml的Activity的IntentFilter中包含 android.category.DEFAULT,这样所有不设置Category(Intent.addCategory(String c);)的 Intent都会与这个Category匹配。

4、extras(附加信息),是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如 果要执行 发送电子邮件 这个动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。

1.SQLite

图形化界面来查看数据库,使用Sqliteman

>sudo apt-get install sqliteman

2.关于Activity间的跳转

>1.Intent it = getIntent();

>2.Intent it = new Intent();

说说第一种,假设注册了个单击跳转的事件,第一次点击是有反应的,现在退出整个应用程序,再次启动,此时的单击事件都失效,其他的监听事件都没问 题,就属单击事件.

3.关于ListView 和 ExpandableListView这种列表控件

Java代码

@Override

public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {

ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo;

int type = ExpandableListView.getPackedPositionType(info.packedPosition);

if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {

String title = ((TextView) info.targetView.findViewById(R.id.groupName)).getText().toString();

menu.setHeaderTitle(title);

menu.add(0, MENU_GROUP_ADD, 0, "添加分组");

menu.add(0, MENU_GROUP_DELETE, 0, "删除分组");

menu.add(0, MENU_GROUP_MODIFY, 0, "重命名");

menu.add(0, MENU_GROUP_ADDCONTACT, 0, "添加联系人");

} else if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {

String title = ((TextView) info.targetView.findViewById(R.id.chats_view_name)).getText().toString();

menu.setHeaderTitle(title);menu.add(0, MENU_CONTACTS_DELETE, 0, "删除联系人");

menu.add(0, MENU_CONTACTS_MODIFY, 0, "编辑联系人");

menu.add(0, MENU_CONTACTS_MOVE, 0, "移动联系人到...");}

}

@Override

public boolean onContextItemSelected(MenuItem item) {

ExpandableListContextMenuInfo menuInfo = (ExpandableListContextMenuInfo) item.getMenuInfo();

int type = ExpandableListView.getPackedPositionType(menuInfo.packedPosition);

if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {

String groupName = ((TextView) menuInfo.targetView.findViewById(R.id.groupName)).getText().toString();

Log.i(TAG, groupName);

switch (item.getItemId()) {

case MENU_GROUP_ADD:break;

case MENU_GROUP_DELETE:break;

case MENU_GROUP_MODIFY:break;

case MENU_GROUP_ADDCONTACT:break;

}

} else if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {

String childName = ((TextView) menuInfo.targetView.findViewById(R.id.chats_view_name)).getText().toString();

Log.i(TAG, childName);

switch (item.getItemId()) {

case MENU_CONTACTS_DELETE:break;

case MENU_CONTACTS_MODIFY:break;

case MENU_CONTACTS_MOVE:break;

}

}

return true;

}

如果需要给group或者child 加上个长按事件

这样写了,没反应,需要将实列注册给监听器

Java代码

ExpandableListView mElv = (ExpandableListView) findViewById(android.R.id.list);registerForContextMenu(mElv);

另外需要提到一点的是,我在项目里注册了长按事件,同时group下的child也有个onClick()事件,这时候,onClick()事件无 效

需要给child增加单击事件

Java代码

mElv.setOnChildClickListener(mChildClickListener);// 注册group下的item的点击事件

OnChildClickListener mChildClickListener = new OnChildClickListener() {

@Override

public boolean onChildClick(ExpandableListView parent, View v,int groupPosition, int childPosition, long id) {

// TODO Auto-generated method stub

Intent intent = new Intent();

intent.setClass(Main.this, ChatActivity.class);

startActivity(intent);

return false;

}

};

> 今天发现 想要将列表控件中间的分割符去掉,可以通过android:divider="@null"来设置.

4.让控件显示在底部(不是界面上的底部),也就是从底部开始显示,可以采用android:layout_gravity="bottom", 该控件不能放在相对布局里,否则没效果

5.想做出个跟CSS里的Float效果,可以采用RelativeLayout的嵌套,在子 RelativeLayout里设置android:layout_alignParentRight="true"等一系列属性.

6.ListView中如何使用Button,让onClick和onItemClick事件共存,可以在布 局文件里,将这个Button添加个android:focusable="false"属性

7.EditText控件,让光标停在字符最後

Java代码

EditText inputField = new EditText(this);

Editable eText = inputField.getText();

int position = eText.length();

Selection.setSelection(eText, position);

8.让控件均匀分布,整齐的排列

Java代码

<LinearLayout android:id="@+id/chat_bottom"

android:layout_width="fill_parent" android:layout_height="50dip"

android:orientation="horizontal" android:visibility="gone">

<RelativeLayout android:layout_width="fill_parent"

android:layout_height="wrap_content" android:layout_weight="1.0"

android:layout_gravity="center_vertical">

<Button android:id="@+id/btn_chat_history"

android:layout_width="wrap_content" android:layout_height="wrap_content"

android:background="@drawable/chat_history_button"

android:layout_centerInParent="true" />

</RelativeLayout>

<RelativeLayout android:layout_width="fill_parent"

android:layout_height="wrap_content" android:layout_weight="1.0"

android:layout_gravity="center_vertical">

<Button android:id="@+id/button2" android:layout_width="wrap_content"

android:layout_height="wrap_content" android:background="@drawable/widget_qq"

android:layout_centerInParent="true" />

</RelativeLayout>

<RelativeLayout android:layout_width="fill_parent"

android:layout_height="wrap_content" android:layout_weight="1.0"

android:layout_gravity="center_vertical">

<Button android:id="@+id/back_chats_view"

android:layout_width="wrap_content" android:layout_height="wrap_content"

android:background="@drawable/back_btn"

android:layout_centerInParent="true" />

</RelativeLayout>

</LinearLayout>

9.有时候发现你界面上 有个EditText控件,真机上进入这个界面,会获得焦点,然后弹出一个软键盘出来,可以做如下处理,将焦点给转移.

Java代码

<!-- 使EditText的焦点移到linearlayout上,同时保证EditText还可以获得焦点 -->

<LinearLayout android:focusable="true"

android:focusableInTouchMode="true" android:layout_height="0px"

android:layout_width="0px">

</LinearLayout>

10.控制软件盘的显示与隐藏

Java代码

/**

* 控制软键盘的显示与隐藏

*/

private void opSoftInput(View view, boolean hasFocus){

if(hasFocus){

putMethodManager)getSystemService(INPUT_METHOD_SERVICE)).showSoftInput(view, 0);

} else {

putMethodManager)getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

}

}

11. 上次写了篇关于TextView里解析包含图片的博客,这次去弄了下EditText中,点击表情,将表情图片添加到EditText (类似QQ表情的发送吧)

呵呵,中间走了点弯路,开始是将EditText中的内容拿去解析,还用了正则去匹配,结果失败,

SpannableString类的setSpan(Object what, int start, int end, int flags)

我采用map保存了表情,

看下当时写的重写的EditText的setText()方法

Java代码

@Override

public void setText(CharSequence text, BufferType type) {

// TODO Auto-generated method stub

initFaceMap();

// 需要处理的文本

SpannableString spannable = new SpannableString(text.toString());

if (text != null && faceMap != null) {

// 对表情符以img标记进行修饰,改用drawable显示出来

Set<String> keys = faceMap.keySet();

for (String key : keys) {

if (text.toString().contains(key)) {

Drawable drawable = getResources().getDrawable(faceMap.get(key));

drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

//要让图片替代指定的文字就要用ImageSpan

ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);

int start = text.toString().indexOf(key);

spannable.setSpan(span, start, start + key.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

}

}

}

super.setText(spannable, type);

}

这样写,如果有输入相同的表情,则只有第一个显示正常,后续的都是字符,因为我只遍历了一遍map,而且是替换了一遍.

下面是简单方法(需要在布局文件里给每个表情按钮添加一个tag属性,展示的是表情,实质内容还是tag的文本,方便接收方的解析)

Java代码

/** 聊天表情图片监听器 */

private OnClickListener faceImageButtonListener = new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

ImageButton imageButton = (ImageButton) v;

String emotionTag = imageButton.getTag().toString();

int cursor = content.getSelectionEnd();

content.getText().insert(cursor, emotionTag);

SpannableString spannable = new SpannableString(content.getText());

Drawable draw = imageButton.getDrawable();

ImageSpan span = new ImageSpan(draw, ImageSpan.ALIGN_BASELINE);

// 下面flags参数换成Spannable.SPAN_INCLUSIVE_EXCLUSIVE,会导致添加了表情后,无法删除表情,也无法输入字符

spannable.setSpan(span, cursor, cursor + emotionTag.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

content.setText(spannable);

Editable eText = content.getText();

Selection.setSelection(eText, content.getText().length());// 控制光标显示在字符最后

}

};

最后贴上效果图

赞助本站

人工智能实验室

相关热词: Android 基本概念

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港