SunShine学习总结

来源:互联网 发布:嵌入式软件测试策略 编辑:程序博客网 时间:2024/04/28 08:02

(1)勉强加上了ContentProvider,发现一个问题就是自己的第一次进入没有把数据刷出来,然后各种调试,最后发现

我在碎片onCreate方法中调用了更新数据的函数

updateWeather

这个时候,异步任务执行返回

@Overrideprotected void onPostExecute(String[] result) {    if (result != null && mForecastAdapter != null) {        mForecastAdapter.clear();        mForecastAdapter.addAll(result);        // New data is back from the server.  Hooray!    }}

由于mForcastAdapter是在碎片的onCreateView中创建的,所以这个时候这个mForecastAdapter是null,

和项目代码比较,发现,人家在

onStart方法中调用updateWeather,这样就ok了,我我们看看碎片的生命周期啊



onCreateView在onCreate之后调用,所以之前自己在ONCreate调用,会导致adapter没有在onCreateVIew初始化,所以刷新不出来啊,

总算搞明白了,哈哈哈。


2.另外ContentResolver连接我们数据和应用的接口,所有访问都用它,不要在用数据库查询了,封装的多好。

比如下面这个方法,自己一开始就是使用数据库,先得到database,然后在操作,直接使用ContentResolver就好了,query和insert都简单,

有一点就是插入从返回的Uri重提取id,

 locationId = ContentUris.parseId(insertedUri);


对于数据库,插入就是直接返回rowID,但是ContentResolver返回的是一个URi,不过我们可以直接使用ContentUris的方法帮我们解析id,多好啊。



long addLocation(String locationSetting, String cityName, double lat, double lon) {    // Students: First, check if the location with this city name exists in the db    // If it exists, return the current ID    long locationId;    Cursor cursor = mContext.getContentResolver().query(WeatherContract.LocationEntry.CONTENT_URI,            new String[]{WeatherContract.LocationEntry._ID},            WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING + "= ? ",            new String[]{locationSetting},            null    );    if(cursor.moveToFirst()){        int index  = cursor.getColumnIndex(WeatherContract.LocationEntry._ID);        locationId = cursor.getLong(index);    }else {        ContentValues contentValues = new ContentValues();        contentValues.put(WeatherContract.LocationEntry.COLUMN_CITY_NAME, cityName);        contentValues.put(WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING, locationSetting);        contentValues.put(WeatherContract.LocationEntry.COLUMN_COORD_LAT, lat);        contentValues.put(WeatherContract.LocationEntry.COLUMN_COORD_LONG, lon);        // Finally, insert location data into the database.        Uri insertedUri = mContext.getContentResolver().insert(                                   WeatherContract.LocationEntry.CONTENT_URI,                contentValues );                          // The resulting URI contains the ID for the row.  Extract the locationId from the Uri.        locationId = ContentUris.parseId(insertedUri);    }   cursor.close();    return  locationId;}


3.现在还有的问题是

先查询数据库,然后在从网络获取。

同时还希望从网络查询数据,避免在UI Thread执行查询操作,这回导致安卓不能足够快的绘制帧,会导致帧速率抖动,为此安卓提供了

加载器模式,是不是就是CursorLoader 了。

4.接着昨天,今天学习CursorLoader,定义了一个ForecastAdapter,一般有simplerCursorAdapter吧,不知道为什么这么定义,好了,既然定义了,

那么以后再学习,关键是创建loader的时候,有个问题,

在onActivityCreate方法中,不需要进行UI更新操作,而自己做了,和官方文档一样做的。实际sunshine使用的是,

在OnCreateVIew传入的cursors null,那么这个适配器的数据是怎么和CursorLoader挂上的呢,真是不理解。

有下面这句,这就是把adapter和我们的Cursor关联上了,虽然一开始的null,但是后来变了,所以就一起变了,哈哈哈,是吧

@Overridepublic void onLoadFinished(android.support.v4.content.Loader<Cursor> loader, Cursor data) {    adapter.swapCursor(data);}


@Override public View onCreateView(LayoutInflaterinflater,ViewGroupcontainerBundle savedInstanceState) { // The CursorAdapter will take data from our cursor and populate the ListView. mForecastAdapter = new ForecastAdapter(getActivity(), null, 0);   View rootView = inflater.inflate(R.layout.fragment_main, container,false);   // Get a reference to the ListView, and attach this adapter to it. ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast); listView.setAdapter(mForecastAdapter);   return rootView; }   @Override public void onActivityCreated(BundlesavedInstanceState) { getLoaderManager().initLoader(FORECAST_LOADER,null,this); super.onActivityCreated(savedInstanceState); }

@Override public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { String locationSetting = Utility.getPreferredLocation(getActivity());   // Sort order: Ascending, by date. String sortOrder = WeatherContract.WeatherEntry.COLUMN_DATE+" ASC"Uri weatherForLocationUri = WeatherContract.WeatherEntry.buildWeatherLocationWithStartDate( locationSetting, System.currentTimeMillis());   return new CursorLoader(getActivity(), weatherForLocationUri, nullnullnull, sortOrder); }



5.直接在onLoadFinished修改对吗,这是在UI线程的吗,为什么,然后直接使用CurSor,如果不先使用

 if (!data.moveToFirst()) { return; }

就是要先moveToFirst,然后在调用get方法才行,这是为什么?

报错,这是为什么?

 android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1




public void onLoadFinished(Loader<Cursor> loader, Cursor data) {    if (!data.moveToFirst()) { return; }    String desc = data.getString(COL_WEATHER_DESC);    TextView detailTextView = (TextView)getView().findViewById(R.id.day_info);    detailTextView.setText(desc);


6.Fragment的menu会汇总到所在Activity的menu中,就如Sunshine的MainActivity中的menu和包含的碎片的menu就合在一起了

main的menu

<menu xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">    <item android:id="@+id/action_settings"        android:title="@string/action_settings"        android:orderInCategory="100"        app:showAsAction="never" />    <item android:id="@+id/action_map"        android:title="@string/action_map"        app:showAsAction="never" /></menu>

碎片的:

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:syapp="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_fresh"     android:title="@string/fresh"     syapp:showAsAction="never"    ></item></menu>

最后显示的是这两个之和,一共三个按钮啊


7、字符串格式化,里面的id是什么意思,还是要看文档继续学习

<resources  xmlns:xliff="http://schemas.android.com/apk/res-auto">

<string name="format_full_friendly_date"><xliff:g id="day">%1$s</xliff:g>, <xliff:g id="date">%2$s</xliff:g></string><string name="format_temperature"><xliff:g id="temp1">%1.0f</xliff:g>\u00B0</string>

8、在OnCreateView方法中,把一个个的view作为成员变量保存,不用每次都加载??

@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,                         Bundle savedInstanceState) {    View rootView = inflater.inflate(R.layout.fragment_detail, container, false);    mIconView = (ImageView) rootView.findViewById(R.id.detail_icon);    mDateView = (TextView) rootView.findViewById(R.id.detail_date_textview);    mFriendlyDateView = (TextView) rootView.findViewById(R.id.detail_day_textview);    mDescriptionView = (TextView) rootView.findViewById(R.id.detail_forecast_textview);    mHighTempView = (TextView) rootView.findViewById(R.id.detail_high_textview);    mLowTempView = (TextView) rootView.findViewById(R.id.detail_low_textview);    mHumidityView = (TextView) rootView.findViewById(R.id.detail_humidity_textview);    mWindView = (TextView) rootView.findViewById(R.id.detail_wind_textview);    mPressureView = (TextView) rootView.findViewById(R.id.detail_pressure_textview);    return rootView;}

0 0