直接在布局文件mainxml中定义好你的界面,然后在Activity的onCreate方法中通过setContentView来使用这个布局。
加载某个View的话,可以通过findViewByID来获得它,然后直接编程赋值就可以了。
使用Broadcast广播即可
android系统中,BroadcastReceiver的设计初衷就是从全局考虑的,可以方便应用程序和系统、应用程序之间、应用程序内的通信
在获取消息activity中建立BroadcastReceiver内部类,并且注册广播
示例代码如下
//接受消息的activitypublic class MainActivity extends Activity {
private InnerReceiver receiver = new InnerReceiver();
@Override
protected void onCreate(Bundle savedInstanceState) {
superonCreate(savedInstanceState);
setContentView(Rlayoutactivity_main);
}
@Override
protected void onRestart() {
superonRestart();
//注册广播
IntentFilter filter = new IntentFilter("test");
registerReceiver(receiver, filter);
}
@Override
protected void onStop() {
superonStop();
取消广播
unregisterReceiver(receiver);
}
public class InnerReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//使用intent获取发送过来的数据
String msg = intentgetStringExtra("msg");
}
}
}package comexampledemo;
import androidappActivity;
import androidcontentIntent;
import androidosBundle;
import androidviewView;
import androidviewViewOnClickListener;
import androidwidgetButton;
import androidwidgetEditText;
//发送消息的activity
public class SendActivity extends Activity {
private Button btn;
private EditText text;
@Override
protected void onCreate(Bundle savedInstanceState) {
superonCreate(savedInstanceState);
setContentView(Rlayoutactivity_main);
btn = (Button)findViewById(Ridbutton);
text = (EditText)findViewById(Ridtext);
btnsetOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("test");
intentputExtra("msg", textgetText()toString());
sendBroadcast(intent);
}
});
}
}
您可能听说过View ,ViewManager,Window,PhoneWindow,WindowManager,WindowManagerService,可是你知道这几个类是什么关系,干嘛用的。概括的来说,View是放在Window中的,Window是一个抽象类,它的具体实现是PhoneWindow,PhoneWindow还有个内部类DecorView,WindowManager是一个interface,继承自ViewManager,它是外界访问Window的入口,,提供了add/remove/updata的方法 *** 作View,WindowManager与WindowManagerSerice是个跨进程的过程,WindowManagerService的职责是对系统中的所有窗口进行管理。如果您不太清楚,建议往下看,否则就不要看了。
Android系统的Window有很多种,大体上来说,Framework定义了三种窗口类型;
这就是Framework定义了三种窗口类型,这三种类型定义在WindowManager的内部类LayoutParams中,WindowManager讲这三种类型 进行了细化,把每一种类型都用一个int常量来表示,这些常量代表窗口所在的层,WindowManagerService在进行窗口叠加的时候,会按照常量的大小分配不同的层,常量值越大,代表位置越靠上面, 所以我们可以猜想一下,应用程序Window的层值常量要小于子Window的层值常量,子Window的层值常量要小于系统Window的层值常量。 Window的层级关系如下所示。
上面说了Window分为三种,用Window的type区分,在搞清楚Window的创建之前,我们需要知道怎么去描述一个Window,我们就把Window当做一个实体类,给我的感觉,它必须要下面几个字段。
实际上WindowManagerLayoutParams对Window有很详细的定义。
提取几个重要的参数
Window是一个是一个抽象的概念,千万不要认为我们所看到的就是Window,我们平时所看到的是视图,每一个Window都对应着一个View,View和Window通过ViewRootImpl来建立联系。有了View,Window的存在意义在哪里呢,因为View不能单独存在,它必须依附着Window,所以有视图的地方就有Window,比如Activity,一个Dialog,一个PopWindow,一个菜单,一个Toast等等。
通过上面我们知道视图和Window的关系,那么有一个问题,是先有视图,还是先有Window。这个答案只有在源码中找了。应用程序的入口类是ActivityThread,在ActivityThread中有performLaunchActivity来启动Activity,这个performLaunchActivity方法内部会创建一个Activity。
如果activity不为null,就会调用attach,在attach方法中通过PolicyManager创建了Window对象,并且给Window设置了回调接口。
PolicyManager的实现类是Policy
这样Window就创建出来了, 所以先有Window,后有视图,视图依赖Window存在 ,再说一说视图(Activity)为Window设置的回调接口。
Activity实现了这个回调接口,当Window的状态发生变化的时候,就会回调Activity中实现的这些接口,有些回调接口我们还是熟悉的,dispatchTouchEvent,onAttachedToWindow,onDetachedFromWindow等。
下面分析view是如何附属到window上的,通过上面可以看到,在attach之后就要执行callActivityOnCreate,在onCreate中我们会调用setContentView方法。
getWindow获取了Window对象,Window的具体实现类是PhoneWindow,所以要看PhoneWindow的setContentView方法。
这里涉及到一个mContentParent变量,他是一个DecorView的一部分,DecorView是PhoneWindow的一个内部类,我先介绍一下关于DecorView的知识。
DecorView是Activity的顶级VIew,DecorView继承自FrameLayout,在DecorView中有上下两个部分,上面是标题栏,下面是内容栏,我们通过PhoneWindow的setContentView所设置的布局文件是加到内容栏(mContentParent)里面的,View层的事件都是先经过DecorView在传递给我们的View的。
OK在回到setContentView的源码分析,我们可以得到Activity的Window创建需要三步。
- 1、 如果没有DecorView,在installDecor中创建DecorView。
- 2、将View添加到decorview中的mContentParent中。
- 3、回调Activity的onContentChanged接口。
先看看第一步,installDecor的源码
installDecor中调用了generateDecor,继续看
直接给new一个DecorView,有了DecorView之后,就可以加载具体的布局文件到DecorView中了,具体的布局文件和系统和主题有关系。
在看第二步,将View添加到decorview中的mContentParent中。
直接将Activity视图加到DecorView的mContentParent中,最后一步,回调Activity的onContentChanged接口。在Activity中寻找onContentChanged方法,它是个空实现,我们可以在子Activity中处理。
到此DecorView被创建完毕,我们一开始从Thread中的handleLaunchActivity方法开始分析,首先加载Activity的字节码文件,利用反射的方式创建一个Activity对象,调用Activity对象的attach方法,在attach方法中,创建系统需要的Window并为设置回调,这个回调定义在Window之中,由Activity实现,当Window的状态发生变化的时候,就会回调Activity实现的这些回调方法。调用attach方法之后,Window被创建完成,这时候需要关联我们的视图,在handleLaunchActivity中的attach执行之后就要执行handleLaunchActivity中的callActivityOnCreate,在onCreate中我们会调用setContentView方法。通过setContentView,创建了Activity的顶级View---DecorView,DecorView的内容栏(mContentParent)用来显示我们的布局。 这个是我们上面分析得到了一个大致流程,走到这里,这只是添加的过程,还要有一个显示的过程,显示的过程就要调用handleLaunchActivity中的handleResumeActivity方法了。最后会调用makeVisible方法。
这里面首先拿到WindowManager对象,用tWindowManager 的父接口ViewManager接收,ViewManager可以
最后调用 mDecorsetVisibility(ViewVISIBLE)设置mDecor可见。到此,我们终于明白一个Activity是怎么显示在我们的面前了。
参考链接:
>
layout为布局,布局里面可以放任何空间,获取空间可以用findViewById方法获取
android 获取某个布局控件 添加到另一个布局中
protected void onCreate(Bundle savedInstanceState) {
superonCreate(savedInstanceState);
setContentView(Rlayoutactivity_main);
LinearLayout relativeLayout = (LinearLayout) findViewById(Ridlayout456);
ImageView imgApple2 = new ImageView(this);
imgApple2setImageResource(Rdrawableic_launcher);
relativeLayoutaddView(imgApple2);
LayoutInflater factorys = LayoutInflaterfrom(MainActivitythis);
final View textEntryView = factorysinflate(Rlayoutlayout1, null);
// LinearLayout linearLayout = (LinearLayout) textEntryView
// findViewById(Ridlayout1);
// relativeLayoutaddView(linearLayout);
EditText editText1 = (EditText) textEntryView
findViewById(RideditText1);
relativeLayoutaddView(editText1);
以上就是关于Android 如何替代setContentView方法,使得部分视图更新之后其他部分视图还在全部的内容,包括:Android 如何替代setContentView方法,使得部分视图更新之后其他部分视图还在、android怎么从一个activity获取另一个activity的信息、Android源码解析Window系列第(一)篇---Window的基本认识和Activity的加载流程等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)