您的位置:首页 > 移动开发 > Android开发

(大总结)从寻找fragment静态导入activity总是失败的解决方法中了解android应用的系统启动过程

2015-03-14 12:56 861 查看
整整花了我一天时间,终于解决了这个问题,心好累,就不说闲话了,我首先说遇见的问题,在说解决问题的思路方法,

目标:我要在主activity中加入三个独立的fragment

首先activity_main.xml代码如下

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#CCCCCC">

<fragment
android:name="com.yusong.ourclassapp.TopTitleFragment"
android:id="@+id/main_title_top"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_alignParentTop="true"/>

<fragment
android:name="com.yusong.ourclassapp.BottomTitleFragment"
android:id="@+id/main_title_bottom"
android:layout_width="match_parent"
android:layout_height="57dp"
android:layout_alignParentBottom="true"/>

<fragment
android:name="com.yusong.ourclassapp.ViewPagerFragment"
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/main_title_top"
android:layout_above="@id/main_title_bottom"/>

</RelativeLayout>


和各种主流参考书和网上的信息一样,这没有什么问题;run as,应用停止运行了,,仔细查看logcat,发现了三个问题;

1, Caused by: android.view.InflateException: Binary XML file line #19: Error inflating class fragment

2,Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment com.yusong.ourclassapp.main_title_bottom: make sure class name exists, is public, and has an empty constructor that is public

3,Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.yusong.ourclassapp.main_title_bottom” on path: DexPathList[[zip file “/data/app/com.yusong.ourclassapp-2.apk”],nativeLibraryDirectories=[/data/app-lib/com.yusong.ourclassapp-2, /vendor/lib, /system/lib]]

主要原因首先第一个问题是“inflater 填充fragment错误“,通过这个可以定位到重写的fragment的oncreateview()方法;查看各种资料后,inflater主要有两种写法:第一种:inflater.inflate(int resource, ViewGroup root)

第二种:inflater.inflate(int resource, ViewGroup root, boolean attachToRoot)

各参数含义如下:

resource: ID for an XML layout resource to load (e.g., R.layout.main_page)

这是布局是用来填充你在activity_main中声明的fragement的,将会返回一个view对象代替该fragment在activity_main中的位置;

root: Optional view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.)

root是指该fragment所在的父布局,是一个viewgroup类型的,viewgroup类型是什么,各位可自行百度,这里指的就是activity_main的布局的id,默认是container;

attachToRoot: Whether the inflated hierarchy should be attached to the root parameter? If false, root is only used to create the correct subclass of LayoutParams for the root view in the XML.

额。。。这个什么意思,我还没看太明白,一般为false

所以最后方法如下:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

return inflater.inflate(R.layout.main_title_bottom,container,false);
}


第二个问题是:Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment

很明显是fragment不能实例化,,检查后明白两点:第一:你重写的Fragment的类代码必须在所在包底下新建类文件(.java),如BottomTitleFragment.java, 不能直接在MainActivity()中写,切记,因为这个类文件是要在activity_main.xml文件中通过android:name属性直接调用的;

第二:最重要也最容易忽略的是XML文件中那个不起眼的android:name的作用,;非常非常的重要,请牢记它的正确写法是”完整包名+你新建的该fragment的Class类的名字“(而不是其XML文件的名字),此属性决定了系统在调用R.layout.activity_main布局时实例化那个fragment;

此处小结:activity的启动过程是

1,AndroidManifest中配置要启动的应用是MainActivity,调用该方法

<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>


调用MainActivity ,应用开始启动

public class MainActivity extends FragmentActivity{

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}


使用setContentView(R.layout.activity_main); 填充view构建Activity的页面,调用R.layout.activity_main布局文件时,根据检测到的fragment的android:name属性,例如:android:name=”com.yusong.ourclassapp.TopTitleFragment”,自动调用包底下写好的TopTitleFragment类实例化该fragment对象(该类在内部已通过inflater方法填充对应好了各个fragment的XML布局),返回View替换在activity_main中的位置,通过这样,有机的把各个xml布局文件结合联系到了一起,组成了一个完整紧凑的View,因此就可以在activity页面上的显示出来了。

到这里前面出现的问题已经完整解决了,我充满信心的再次run,结果程序有一次停止运行了,从logcat上找到了以下两个问题:

Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class fragment

Caused by: java.lang.ClassCastException: com.yusong.ourclassapp.TopTitleFragment cannot be cast to android.app.Fragment

按说应该没有问题了,怎么又出现问题了,唉,好好分析一下吧,通过XML file line #10,我们可以知道问题出现在xml文件的第10行,第十行是什么呢


就是一个fragment标签啊,没什么其他的,通过网上查找各种答案,

讨论主要集中在了android.support.v4包的问题,因为低版本SDK不支持fragment,所以就出现了支持包的问题,仔细检查我的工程,我发现,因为我初始化建activity是选择了empty activity,什么也没有,既不是blank activity,也不是blank activity with fragment,因此我工程中的MainActivity导入的是android.app.Activity包,继承的是activity,而我的fragment中依赖的包是android.support.v4.app.Fragment;很明显不配套,如下:





所以我把MainActivity extends 改为了继承FragmentActivity,程序自动导入了android.support.v4.app.FragmentActivity包,如下:



最后高兴的Run了一下,果然兴奋的完美解决了问题!!!!

总结:在这次这个小问题的解决中,虽然问题不大,但是我在寻找答案的过程中,对Android应用的程序框架,结构,生命周期,还有各种基础细节知识了解的更加全面了,在学会了通过logcat查找问题根源,还有异常处理,程序构架等都有了更深的理解,希望我能在接下来的学习中走的更快,早日成长为技术高手!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐