最近看《第一行代码》的案例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>
最后应用界面如下: