最近看《第一行代碼》的案例coolweather,就照着書上碼代碼了,因為版本原因,遇到了一些坑,記以留念
coolweather源碼:https://gitee.com/imoonfish/coolweather
遇到第一個問題是intent問題,軟件編譯,沒有問題,但是運行起來就閃退啊!logcat里面顯示的是intent傳輸的數據太大導致閃退,但是查看代碼,傳輸的明明就是幾個字節的數據,怎么會太大了!最后,尷尬的發現,沒有在AndroidManifest.xml里面注冊這個活動,我們在AndroidManifest.xml注冊該活動,添加如下代碼,問題解決!
<activity android:name=".WeatherActivity"/>
這里我inten跳轉的是WeatherActivity.class這個活動,所以這里寫的是WeatherActivity
遇到的第二個問題是 Android.Support.v4的問題,就是在寫xml界面時候,我們想要使用下滑刷新功能和側滑功能,書上用的是support.v4這個包,但是啊我們最新版本寫這個,它識別不出,顯示沒有這個包。查了資料發現,最新版本應該使用下面這兩個玩意兒!
androidx.drawerlayout.widget.DrawerLayout
androidx.swiperefreshlayout.widget.SwipeRefreshLayout
在activity_weather.xml中具體的xml界面如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/bing_pic_img"
android:scaleType="centerCrop"
android:contentDescription="TODO" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never"
android:id="@+id/weather_layout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:fitsSystemWindows="true">
<include layout="@layout/title"/>
<include layout="@layout/now"/>
<include layout="@layout/forecast"/>
<include layout="@layout/aqi"/>
<include layout="@layout/suggestion"/>
</LinearLayout>
</ScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<fragment
android:id="@+id/choose_area_fragment"
android:name="com.moyu.coolweather.ChooseAreaFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
tools:layout="@layout/choose_area" />
</androidx.drawerlayout.widget.DrawerLayout>
</FrameLayout>
然后在相關的java文件(WeatherActivity.class)里導入相應的包,問題解決
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
哦!還有添加依賴,Android Studio沒有自動幫你在build.gradle(Module:app)里面添加依賴的話,你需要手動添加
implementation 'androidx.appcompat:appcompat:1.1.0-beta01'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
附上這個項目build.gradle(Module:app)全部代碼:
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '29.0.0'
defaultConfig {
applicationId "com.moyu.coolweather"
minSdkVersion 24
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'org.litepal.android:java:3.0.0'
implementation 'com.squareup.okhttp3:okhttp:4.0.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'androidx.appcompat:appcompat:1.1.0-beta01'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
testImplementation 'junit:junit:4.13-beta-3'
androidTestImplementation 'androidx.test:runner:1.3.0-alpha01'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha01'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
}
小技巧:你想要添加依賴的話,你知道這個依賴包的名字,你可以點擊File->Project Structure然后選擇你的app,點擊加號,添加Library Dependencies,搜索你要添加的依賴包即可,如圖所示:
最后一個問題是服務的問題,intent跳轉到服務,需要在AndroidManifest.xml里面配置相關服務如下:
<service android:name=".service.AutoUpdateService">
<intent-filter>
<action android:name="AutoUpdateService"/>
</intent-filter>
</service>
這里我們跳轉的是AutoUpdateService服務,使用這個服務主要是在后台自動更新數據
這個啟動服務的代碼要寫在WeatherActivity.java文件的showWeatherInfo(Weather weather){ }這個方法里面,最終項目方法中所有的代碼如下:
/**
* 處理並展示Weather實體類中的數據
*/
private void showWeatherInfo(Weather weather){
String cityName=weather.basic.cityName;
String updateTime=weather.basic.update.updateTime.split(" ")[1];
String degree=weather.now.temperature+"℃";
String weatherInfo=weather.now.mroe.info;
titleCity.setText(cityName);
titleUpdateTime.setText(updateTime);
degreeText.setText(degree);
weatherInfoText.setText(weatherInfo);
forecastLayout.removeAllViews();
for(Forecast forecast:weather.forecastList){
View view = LayoutInflater.from(this).inflate(R.layout.forecast_item,forecastLayout,false);
TextView dateText=view.findViewById(R.id.date_text);
TextView infoText=view.findViewById(R.id.info_text);
TextView maxText=view.findViewById(R.id.max_text);
TextView minText=view.findViewById(R.id.min_text);
dateText.setText(forecast.date);
infoText.setText(forecast.more.info);
maxText.setText(forecast.temperature.max);
minText.setText(forecast.temperature.min);
forecastLayout.addView(view);
}
if(weather.aqi!=null){
aqiText.setText(weather.aqi.city.aqi);
pm25Text.setText(weather.aqi.city.pm25);
}
String comfort="舒適度:"+weather.suggestion.comfort.info;
String carWash="洗車指數:"+weather.suggestion.carWash.info;
String sport="運動建議:"+weather.suggestion.sport.info;
comfortText.setText(comfort);
carWashText.setText(carWash);
sportText.setText(sport);
weatherLayout.setVisibility(View.VISIBLE);
Intent intent=new Intent(this,AutoUpdateService.class);
startService(intent);
}
其他的代碼照着《第一行代碼》的內容敲就完事了!
注意:如果google源速度太慢,可以使用阿里雲鏡像倉庫,只需在build.gradle(Project:coolweather)里面添加阿里雲倉庫地址
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/' }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
整個項目AndroidManifest.xml最終配置如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.moyu.coolweather">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name="org.litepal.LitePalApplication"
android:allowBackup="true"
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".WeatherActivity"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".service.AutoUpdateService">
<intent-filter>
<action android:name="AutoUpdateService"/>
</intent-filter>
</service>
</application>
</manifest>
最后應用界面如下: