当前位置:首页 » 安卓系统 » androidlistitem

androidlistitem

发布时间: 2022-06-26 02:32:36

⑴ android怎样选中listview中一行进行删除

声明这个ListvIew

/生成动态数组,加入数据

listItem = new ArrayList<HashMap<String, Object>>();

map = new HashMap<String, Object>();

for(int i=0;i<10;i++)

{

// 后台数据

HashMap<String, Object> map = new HashMap<String, Object>();

map.put("ItemImage", R.drawable.checked);来下

map.put("ItemTitle", "Level ");

map.put("ItemText", "Finished in 1 Min 54 Secs, 70 Moves!");

listItem.add(map);

}

list.setOnItemClickListener(new OnItemClickListener()

{

@Override

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3)

{

删除操作

listItem.remove(position);//选择行的位置

listItemAdapter.notifyDataSetChanged();

list.invalidate();

listview会删除选择的行,重新更新

}

});

⑵ android 中listview 的用法

1.在xml里面定义一个ListView,这个xml是一个activity的layout文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ListView android:layout_width="wrap_content" //定义一个listView
android:layout_height="wrap_content"
android:id="@+id/ListView01"
/>
</LinearLayout>

2.定义ListView每个条目的Layout,比如命名为listview_item.xml,用RelativeLayout实现:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/RelativeLayout01"
android:layout_width="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:paddingBottom="4dip"
android:paddingLeft="12dip"
android:paddingRight="12dip">
<ImageView
android:paddingTop="12dip"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ItemImage"
/>
<TextView
android:text="TextView01"
android:layout_height="wrap_content"
android:textSize="20dip"
android:layout_width="fill_parent"
android:id="@+id/ItemTitle"
/>
<TextView
android:text="TextView02"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_below="@+id/ItemTitle"
android:id="@+id/ItemText"
/>
</RelativeLayout>

3.在Activity里面调用和加入Listener,具体见注释:
package com.ray.test;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.AdapterView.OnItemClickListener;

public class TestListView extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//绑定Layout里面的ListView
ListView list = (ListView) findViewById(R.id.ListView01);

//生成动态数组,加入数据
ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();
for(int i=0;i<10;i++)
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("ItemImage", R.drawable.checked);//图像资源的ID
map.put("ItemTitle", "Level "+i);
map.put("ItemText", "Finished in 1 Min 54 Secs, 70 Moves! ");
listItem.add(map);
}
//生成适配器的Item和动态数组对应的元素,这里用SimpleAdapter作为ListView的数据源
//如果条目布局比较复杂,可以继承BaseAdapter来定义自己的数据源。
SimpleAdapter listItemAdapter = new SimpleAdapter(this,listItem,//数据源
R.layout.list_items,//ListItem的XML实现
//动态数组与ImageItem对应的子项
new String[] {"ItemImage","ItemTitle", "ItemText"},
//ImageItem的XML文件里面的一个ImageView,两个TextView ID
new int[] {R.id.ItemImage,R.id.ItemTitle,R.id.ItemText}
);

//添加并且显示
list.setAdapter(listItemAdapter);

//添加点击
list.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
setTitle("点击第"+arg2+"个项目");
}
});

//添加长按点击
list.(new OnCreateContextMenuListener() {

@Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
menu.setHeaderTitle("长按菜单-ContextMenu");
menu.add(0, 0, 0, "弹出长按菜单0");
menu.add(0, 1, 0, "弹出长按菜单1");
}
});
}

//长按菜单响应函数
@Override
public boolean onContextItemSelected(MenuItem item) {
setTitle("点击了长按菜单里面的第"+item.getItemId()+"个项目");
return super.onContextItemSelected(item);
}
}

⑶ android listview中listitem问题

这涉及到了listView的嵌套,里面的listView需要重写,将让他没有滚动条,listView才能正常显示

⑷ android中怎么让listview的内容全部显示出来

注意,如果listitem里面有textview的话,就当一行处理进行截取数字。
public static void (ListView listView) {
// 获取ListView对应的Adapter WeiboContentAdapter listAdapter = (WeiboContentAdapter) listView.getAdapter(); if (listAdapter == null) { return; } Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setTextAlign(Align.LEFT); LinearLayout listItem; TextView tvContent; int totalHeight = 0; int lineCount = 0; for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目 listItem = (LinearLayout)listAdapter.getView(i, null, listView); tvContent = (TextView) listItem.findViewById(R.id.tv_weibo_detail_content); lineCount = getLineCount(mPaint, ((SpannedString) tvContent.getText()).toString()); tvContent.measure(0, 0); // 计算子项View 的宽高 totalHeight += tvContent.getMeasuredHeight()*lineCount + 60; // 统计所有子项的总高度 } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)) ; // listView.getDividerHeight()获取子项间分隔符占用的高度 // params.height最后得到整个ListView完整显示需要的高度 listView.setLayoutParams(params); }
private static int getLineCount(Paint mPaint, String content) { int index; int count = 0; while(content.length() > 0){ index = mPaint.breakText(content, true, ResolutionUtil.getWPx()/2, null); content = content.substring(index); count++; } return count; }
/** * 动态改变listView的高度 * @param pull */ private void setPullLvHeight(ListView pull){ int totalHeight = 0; for (int i = 0, len = adapter.getCount(); i < len; i++) { //listAdapter.getCount()返回数据项的数目 View listItem = adapter.getView(i, null, pull); listItem.measure(0, 0); //计算子项View 的宽高 totalHeight += listItem.getMeasuredHeight(); //统计所有子项的总高度 } ViewGroup.LayoutParams params = pull.getLayoutParams(); params.height = totalHeight + (pull.getDividerHeight() * (pull.getCount() - 1)); pull.setLayoutParams(params); }

⑸ Android入门 在ListView中如何进行精确的位置设定

在android的开发中,经常会遇到需要主动去设定某条ListItem的位置的需求。设置位置的函数有
ListView.setSelection(int position)
ListView.setSelectionFromTop(int position, int y);
其中
position指的是指定的item的在ListView中的索引,注意如果有Header存在的情况下,索引是从Header就开始算的。
y指的是到ListView可见范围内最上边边缘的距离。
函数有了,现在就是根据自身需求来进行设置。

这次遇到的需求,ListView要求是从下往上展示的,并且当Cursor更新时,要保持住原先的最上方的item(不包括header)的位置不变,然后新的历史数据在原先那条item上方继续向上展示。如图:

ListView从下往上展示,也就是
android:stackFromBottom="true"
但是发现这一属性的设置不会影响索引的排序顺序,也就是item的索引都是从上往下递增的,不会变成从下往上递增。索引为0的item,都是在ListView的最上方的item(或header).

那么当Cursor更新时,原先第一条的索引便会发生变化。要想保持住它(图中的 R)的位置。步骤如下:
(1)获取这一条在新Cursor中的位置(posiition)
(2)获取这一条在更换Cursor后ListView中的位置。
(4)由于ListView的可滚动的属性,我们需要记录更换Cursor前可视的第一条item的索引(ListView.getFirstVisiblePosition())

(3)区分FirstVisiblePosition是0和大于0的情况。由于header,也就是图中的Loading那一条在新数据出来后是会消失的。

(4)当FirstVisiblePosition为0时实际指向的是header,我们要保持位置不变的是header下面第一条(R)的位置。那么此时要设置FirstVisiblePosition为1
(5)当FirstVisiblePosition大于0时实际指向的就是item,但是我们需要设置FirstVisiblePosition为0。*
(6)我们根据FirstVisiblePosition用ListView.getChildAt(int position)函数获取对应的item的View,再根据View.getTop()函数获取到ListView顶部的距离Y。
这样ListView.setSelectionFromTop(int position, int y)所需的两个参数 position 和 y就都有了。
*注解:ListView.getChildAt(int position), 这个position指的是在可视的item中的索引,跟cursor里的位置是大不一样的。可以看看ListView.getChildCount()函数得到个数是小于或等于Cursor里的个数的(不考虑header的话)。虽然一共可能有20条数据,但是界面只能看到8条,那么这个ChildCount大约就是8了。另一方面, FirstVisiblePosition取出的是在总的条数中的索引,再将会消失的header考虑进来,所以就是 FirstVisiblePosition为0时要设为1,大于0时又要设为0。
下面上代码:
调用的代码:

int headerCount = mListContainer.getListView().getHeaderViewsCount();
int firstVisiblePos = mListContainer.getListView().getFirstVisiblePosition();
int newCursorPosition = getPositionInNewCursor(cursor.getCount(), firstVisiblePos);
int offsetY = getOffsetY(cursor, firstVisiblePos, newCursorPosition);

mAdapter.changeCursor(cursor);

mUpRefreshLayout.setVisibility(View.GONE);

mListContainer.getListView().setSelectionFromTop(newCursorPosition + headerCount, offsetY);
getPositionInNewCursor函数:

private int getPositionInNewCursor(int newCursorCount, int firstVisiblePos){
if(firstVisiblePos == 0){
firstVisiblePos += 1;
}

int headerCount = mListContainer.getListView().getHeaderViewsCount();
int newCursorPos = newCursorCount - mAdapter.getCount() + firstVisiblePos - headerCount;

return newCursorPos;
}
getOffsetY函数:

private int getOffsetY(Cursor cursor, int firstVisiblePos, int newCursorPosition){
int y;

View firstVisibleItem = null;
if(firstVisiblePos == 0){
firstVisibleItem = mListContainer.getListView().getChildAt(1);
}else{
firstVisibleItem = mListContainer.getListView().getChildAt(0);
}
y = firstVisibleItem.getTop();

View timeView = firstVisibleItem.findViewById(R.id.time_text_view);
if(timeView != null && timeView.getVisibility() == View.VISIBLE){

Cursor curItem = (Cursor)mAdapter.getItem(newCursorPosition);
Cursor preItem = (Cursor)mAdapter.getItem(newCursorPosition - 1);
if(curItem != null || preItem != null){
long curTimeStamp = curItem.getLong(MessagesProjection.JEDI_CREATE_DATE_INDX);
long preTimeStamp = preItem.getLong(MessagesProjection.JEDI_CREATE_DATE_INDX);

if(Math.abs(curTimeStamp - preTimeStamp) <= SHOW_TIME_STAMP_TEN_MINS){
LayoutParams param = (LinearLayout.LayoutParams)mTimeView.getLayoutParams();
y += mTimeView.getHeight() + param.topMargin + param.bottomMargin;
}
}
}

return y;
}

getOffsetY中有一段计算图中TimeStamp的高度的代码,不关心的可以自己跳过一下。因为查询出历史数据后可能会造成原先有TimeStamp的那一条在刷新后不再显示TimeStamp(与上一条合并到一个时间段了),所以要把它的高度也计算进去。

⑹ 如何清空android ListView控件的内容

【清空android ListView控件的内容方法】:

1,当我们要加载item的时候,首先把list清空

list.clear();

适配器

adapter1=newArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_list_item_1,list);

listView.setAdapter(adapter1);

这样加载以后就把Listview中的数据清空了。

2、然后再加载我们想要的数据

list.add("a");

list.add("c");

list.add("b");

list.add("a");

list.add("c");

list.add("b");

适配器

adapter1=newArrayAdapter<String>

(getApplicationContext(),android.R.layout.simple_list_item_1,list);

listView.setAdapter(adapter1);


adapter1=newArrayAdapter<String>

(getApplicationContext(),android.R.layout.simple_list_item_1,list);


listView.setAdapter(adapter1);

⑺ android listview怎么用

Android listview与adapter用法
listview与adapter用法

一个ListView通常有两个职责。
(1)将数据填充到布局。
(2)处理用户的选择点击等操作。
第一点很好理解,ListView就是实现这个功能的。第二点也不难做到,在后面的学习中读者会发现,这非常简单。
一个ListView的创建需要3个元素。
(1)ListView中的每一列的View。
(2)填入View的数据或者图片等。
(3)连接数据与ListView的适配器。
也就是说,要使用ListView,首先要了解什么是适配器。适配器是一个连接数据和AdapterView(ListView就是一个典型的AdapterView,后面还会学习其他的)的桥梁,通过它能有效地实现数据与AdapterView的分离设置,使AdapterView与数据的绑定更加简便,修改更加方便
Android中提供了很多的Adapter,表4-5列出了常用的几个。
表4-5 常用适配器

Adapter

含义

ArrayAdapter<T>

用来绑定一个数组,支持泛型操作

SimpleAdapter

用来绑定在xml中定义的控件对应的数据

SimpleCursorAdapter

用来绑定游标得到的数据

BaseAdapter

通用的基础适配器

其实适配器还有很多,要注意的是,各种Adapter只不过是转换的方式和能力不一样而已。下面就通过使用不同的Adapter来为ListView绑定数据(SimpleCursorAdapter暂且不讲,后面讲SQLite时会介绍)。
4.12.1 ListView使用ArrayAdapter
用ArrayAdapter可以实现简单的ListView的数据绑定。默认情况下,ArrayAdapter绑定每个对象的toString值到layout中预先定义的TextView控件上。ArrayAdapter的使用非常简单。
实例:
工程目录:EX_04_12
在布局文件中加入一个ListView控件。

<?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="
http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
android:layout_height="fill_parent"> <!-- 添加一个ListView控件 --> <ListView
android:id="@+id/lv" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
</LinearLayout>

然后在Activity中初始化。

publicclass MyListView extends Activity {

privatestaticfinal String[] strs = new String[] {
"first", "second", "third", "fourth", "fifth"
};//定义一个String数组用来显示ListView的内容private ListView lv;/** Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);

lv = (ListView) findViewById(R.id.lv);//得到ListView对象的引用 /*为ListView设置Adapter来绑定数据*/
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, strs));

}
}

▲图4-29 ListView使用ArrayAdapter运行效果
代码非常的简单,运行效果如图4-29所示。

分析一下使用的步骤。
(1)定义一个数组来存放ListView中item的内容。
(2)通过实现ArrayAdapter的构造函数来创建一个ArrayAdapter的对象。
(3)通过ListView的setAdapter()方法绑定ArrayAdapter。
其中第二步有必要说一下的是,ArrayAdapter有多个构造函数,例子中实现的是最常用的一种。第一个参数为上下文,第二个参数为一个包含TextView,用来填充ListView的每一行的布局资源ID。第三个参数为ListView的内容。其中第二个参数可以自定义一个layout,但是这个layout必须要有TextView控件。通常我们使用Android提供的资源,除了例子中所用的,常用的还有如下几种,可实现带RadioButton和CheckBox的ListView。
(1)通过指定android.R.layout.simple_list_item_checked这个资源,实现带选择框的ListView。需要用setChoiceMode()方法设定选择为多选还是单选,否则将不能实现选择效果,运行效果如图4-30所示。
实现代码如下:
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_checked, strs));
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

(2)通过指定android.R.layout.simple_list_item_multiple_choice这个资源实现带CheckBox的ListView。同样的,需要用setChoiceMode()方法来设置单选或者多选,运行效果如图4-31所示。
实现代码如下:
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice, strs));
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

(3)通过指定android.R.layout.simple_list_item_single_choice这个资源实现带RadioButton的ListView。这里要注意的是,这里并不是指定了单选。是多选还是单选要通过setChoiceMode()方法来指定,运行效果如图4-32所示。
实现代码如下:

lv.setAdapter(newArrayAdapter<String>(this,

android.R.layout.simple_list_item_single_choice,strs));

lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

在前面讲到过,ListView的职责除了填充数据外,还要处理用户的操作。通过如下的代码就可以为ListView绑定一个点击监听器,点击后在标题栏显示点击的行数。

lv.setOnItemClickListener(new OnItemClickListener() {

@Override
publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
//点击后在标题上显示点击了第几行 setTitle("你点击了第"+arg2+"行");
}
});

4.12.2 ListView使用SimpleAdapter
很多时候需要在列表中展示一些除了文字以外的东西,比如图片等。这时候可以使用SimpleAdapter。SimpleAdapter的使用也非常简单,同时它的功能也非常强大。可以通过它自定义ListView中的item的内容,比如图片、多选框等。看一个例子,实现一个每一行都有一个ImageView和TextView的ListView。先看一下运行效果,如图4-34所示。

▲图4-34 带图标的ListView

首先在布局文件中增加一个ListView控件。
还需要定义一个ListView中每一行的布局,用RelativeLayout来实现一个带两行字和一个图片的布局。
item.xml:

<?xmlversion="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent" android:layout_width="fill_parent">
<ImageViewandroid:layout_alignParentRight="true" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/ItemImage"/>
<TextViewandroid:id="@+id/ItemTitle" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:textSize="20sp"/>
<TextViewandroid:id="@+id/ItemText" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:layout_below="@+id/ItemTitle"/> </RelativeLayout>

配置完毕,就可以在Java代码中为ListView绑定数据。

publicclass MyListViewSimple extends Activity {

private ListView lv;
/** Called when the activity is first created. */ @Override
publicvoid onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);

lv = (ListView) findViewById(R.id.lv);/*定义一个动态数组*/
ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();/*在数组中存放数据*/
for(int i=0;i<10;i++)
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("ItemImage", R.drawable.icon);//加入图片 map.put("ItemTitle", "第"+i+"行");
map.put("ItemText", "这是第"+i+"行");
listItem.add(map);
}

SimpleAdapter mSimpleAdapter = new SimpleAdapter(this,listItem,//需要绑定的数据
R.layout.item,//每一行的布局//动态数组中的数据源的键对应到定义布局的View中new String[] {"ItemImage"
,"ItemTitle", "ItemText"},
newint[] {R.id.ItemImage,R.id.ItemTitle,R.id.ItemText}
);

lv.setAdapter(mSimpleAdapter);//为ListView绑定适配器 lv.setOnItemClickListener(new
OnItemClickListener() {

@Override
publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
setTitle("你点击了第"+arg2+"行");//设置标题栏显示点击的行
}
});
}
}

使用simpleAdapter的数据一般都是用HashMap构成的列表,列表的每一节对应ListView的每一行。通过SimpleAdapter的构造函数,将HashMap的每个键的数据映射到布局文件中对应控件上。这个布局文件一般根据自己的需要来自己定义。梳理一下使用SimpleAdapter的步骤。
(1)根据需要定义ListView每行所实现的布局。
(2)定义一个HashMap构成的列表,将数据以键值对的方式存放在里面。
(3)构造SimpleAdapter对象。
(4)将LsitView绑定到SimpleAdapter上。
4.12.3 ListView使用BaseAdapter与ListView的优化
在ListView的使用中,有时候还需要在里面加入按钮等控件,实现单独的操作。也就是说,这个ListView不再只是展示数据,也不仅仅是这一行要来处理用户的操作,而是里面的控件要获得用户的焦点。读者可以试试用SimpleAdapter添加一个按钮到ListView的条目中,会发现可以添加,但是却无法获得焦点,点击操作被ListView的Item所覆盖。这时候最方便的方法就是使用灵活的适配器BaseAdapter了。

使用simpleAdapter的数据一般都是用HashMap构成的列表,列表的每一节对应ListView的每一行。通过SimpleAdapter的构造函数,将HashMap的每个键的数据映射到布局文件中对应控件上。这个布局文件一般根据自己的需要来自己定义。梳理一下使用SimpleAdapter的步骤。
(1)根据需要定义ListView每行所实现的布局。
(2)定义一个HashMap构成的列表,将数据以键值对的方式存放在里面。
(3)构造SimpleAdapter对象。
(4)将LsitView绑定到SimpleAdapter上。
4.12.3 ListView使用BaseAdapter与ListView的优化
在ListView的使用中,有时候还需要在里面加入按钮等控件,实现单独的操作。也就是说,这个ListView不再只是展示数据,也不仅仅是这一行要来处理用户的操作,而是里面的控件要获得用户的焦点。读者可以试试用SimpleAdapter添加一个按钮到ListView的条目中,会发现可以添加,但是却无法获得焦点,点击操作被ListView的Item所覆盖。这时候最方便的方法就是使用灵活的适配器BaseAdapter了。

⑻ android 点击listitem时将点击的数据传到另一个activity的输入框中

activity1 list设置lonitemonclick事件,事件里intent传输数据并打开activity2;
activity2获取数据,edittext.setText("获取的数据");
lv_main.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.putExtra("url", "数据");
intent.setClass(OrderListActivity.this, ProctDetailActivity.class);
startActivity(intent);
}
}
});
String url=(String ) getIntent().getSerializableExtra("url");//获取数据

⑼ android怎样选中listview中一行进行删除

AndroidActivity生命周期

onStart()与onResume()有什么区别?

onStart()是activity界面被显示出来的时候执行的,但不能与它交互;

onResume()是当该activity与用户能进行交互时被执行,用户可以获得activity的焦点,能够与用户交互。

Activity启动流程

startActivity最终都会调用startActivityForResult,通过ActivityManagerProxy调用system_server进程中ActivityManagerService的startActvity方法,如果需要启动的Activity所在进程未启动,则调用Zygote孵化应用进程,进程创建后会调用应用的ActivityThread的main方法,main方法调用attach方法将应用进程绑定到ActivityManagerService(保存应用的ApplicationThread的代理对象)并开启loop循环接收消息。ActivityManagerService通过ApplicationThread的代理发送Message通知启动Activity,ActivityThread内部Handler处理handleLaunchActivity,依次调用performLaunchActivity,handleResumeActivity(即activity的onCreate,onStart,onResume)。

深入理解Activity启动流程

Android类加载器

Android平台上虚拟机运行的是Dex字节码,一种对class文件优化的产物,传统Class文件是一个Java源码文件会生成一个.class文件,而Android是把所有Class文件进行合并,优化,然后生成一个最终的class.dex,目的是把不同class文件重复的东西只需保留一份,如果我们的Android应用不进行分dex处理,最后一个应用的apk只会有一个dex文件。

Android中常用的有两种类加载器,DexClassLoader和PathClassLoader,它们都继承于BaseDexClassLoader。区别在于调用父类构造器时,DexClassLoader多传了一个optimizedDirectory参数,这个目录必须是内部存储路径,用来缓存系统创建的Dex文件。而PathClassLoader该参数为null,只能加载内部存储目录的Dex文件。所以我们可以用DexClassLoader去加载外部的apk。

Android消息机制

应用启动是从ActivityThread的main开始的,先是执行了Looper.prepare(),该方法先是new了一个Looper对象,在私有的构造方法中又创建了MessageQueue作为此Looper对象的成员变量,Looper对象通过ThreadLocal绑定MainThread中;
当我们创建Handler子类对象时,在构造方法中通过ThreadLocal获取绑定的Looper对象,并获取此Looper对象的成员变量MessageQueue作为该Handler对象的成员变量;
在子线程中调用上一步创建的Handler子类对象的sendMesage(msg)方法时,在该方法中将msg的target属性设置为自己本身,同时调用成员变量MessageQueue对象的enqueueMessag()方法将msg放入MessageQueue中;
主线程创建好之后,会执行Looper.loop()方法,该方法中获取与线程绑定的Looper对象,继而获取该Looper对象的成员变量MessageQueue对象,并开启一个会阻塞(不占用资源)的死循环,只要MessageQueue中有msg,就会获取该msg,并执行msg.target.dispatchMessage(msg)方法(msg.target即上一步引用的handler对象),此方法中调用了我们第二步创建handler子类对象时覆写的handleMessage()方法,之后将该msg对象存入回收池;
Looper.loop()为什么不会阻塞主线程
Android是基于事件驱动的,即所有Activity的生命周期都是通过Handler事件驱动的。loop方法中会调用MessageQueue的next方法获取下一个message,当没有消息时,基于Linux pipe/epoll机制会阻塞在loop的queue.next()中的nativePollOnce()方法里,并不会消耗CPU。

IdleHandler (闲时机制)

IdleHandler是一个回调接口,可以通过MessageQueue的addIdleHandler添加实现类。当MessageQueue中的任务暂时处理完了(没有新任务或者下一个任务延时在之后),这个时候会回调这个接口,返回false,那么就会移除它,返回true就会在下次message处理完了的时候继续回调。

同步屏障机制(sync barrier)

同步屏障可以通过MessageQueue.postSyncBarrier函数来设置。该方法发送了一个没有target的Message到Queue中,在next方法中获取消息时,如果发现没有target的Message,则在一定的时间内跳过同步消息,优先执行异步消息。再换句话说,同步屏障为Handler消息机制增加了一种简单的优先级机制,异步消息的优先级要高于同步消息。在创建Handler时有一个async参数,传true表示此handler发送的时异步消息。ViewRootImpl.scheleTraversals方法就使用了同步屏障,保证UI绘制优先执行。

View的绘制原理

View的绘制从ActivityThread类中Handler的处理RESUME_ACTIVITY事件开始,在执行performResumeActivity之后,创建Window以及DecorView并调用WindowManager的addView方法添加到屏幕上,addView又调用ViewRootImpl的setView方法,最终执行

⑽ 请问前辈们,在Android里面如何获取listview里listitem的text view的值

通过adapter啊,里面有个getView方法,可以取得组件,然后通过textView.getText().toString()取得值。其实在listView的onItemClickListener()里面的参数View也可以

热点内容
学生信息录入c语言 发布:2025-04-23 10:50:26 浏览:996
美国广播公司综合编译 发布:2025-04-23 10:37:50 浏览:707
java登录验证码 发布:2025-04-23 10:32:57 浏览:597
note3ftp 发布:2025-04-23 10:23:30 浏览:838
服务器地址后面要加端口 发布:2025-04-23 10:14:42 浏览:866
安卓如何关闭自动管理 发布:2025-04-23 09:45:27 浏览:656
shell文件编程 发布:2025-04-23 09:41:43 浏览:12
安卓课程表源码 发布:2025-04-23 09:41:39 浏览:950
黄金的脚本 发布:2025-04-23 09:30:16 浏览:697
线程池在什么地方配置 发布:2025-04-23 09:24:29 浏览:698