先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
正文
这是新建立的接口代码:
package com.easymorse;public interface ICountService { public abstract int getCount();
}
修改后的CountService代码:
package com.easymorse;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;public class CountServiceextends Serviceimplements ICountService { privateboolean threadDisable; privateint count; private ServiceBinder serviceBinder=new ServiceBinder(); public class ServiceBinderextends Binderimplements ICountService{
@Override publicint getCount() { return count;
}
}
@Override
public IBinder onBind(Intent intent) { return serviceBinder;
}
@Override public void onCreate() { super.onCreate(); new Thread(new Runnable() {
@Override publicvoid run() { while (!threadDisable) { try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
count++;
Log.v(“CountService”,"Count is " + count);
}
}
}).start();
}
@Override public void onDestroy() { super.onDestroy(); this.threadDisable= true;
Log.v(“CountService”,“on destroy”);
} /* (non-Javadoc)
* @see com.easymorse.ICountService#getCount() */ public int getCount() { return count;
}
}
服务的注册也要做改动,AndroidManifest.xml文件:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android=“http://schemas.android.com/apk/res/android” package=“com.easymorse” android:versionCode=“1” android:versionName=“1.0”> <applicationandroid:icon=“@drawable/icon” android:label=“@string/app_name”> <activityandroid:name=“.LocalServiceDemoActivity” android:label=“@string/app_name”> <intent-filter> actionandroid:name\=“android.intent.action.MAIN”/ categoryandroid:name\=“android.intent.category.LAUNCHER”/ </intent-filter> </activity> serviceandroid:name\=“CountService”\ <intent-filter> actionandroid:name\=“com.easymorse.CountService”/ </intent-filter> </service> </application> uses-sdkandroid:minSdkVersion\=“3”/
</manifest>
Acitity代码不再通过startSerivce和stopService启动关闭服务,另外,需要通过ServiceConnection的内部类实现来连接Service和Activity。
package com.easymorse;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.util.Log;public class LocalServiceDemoActivity extends Activity { private ServiceConnection serviceConnection= new ServiceConnection() {
@Override publicvoid onServiceConnected(ComponentName name, IBinder service) {
countService = (ICountService) service;
Log.v(“CountService”,“on serivce connected, count is” + countService.getCount());
}
@Override publicvoid onServiceDisconnected(ComponentName name) {
countService =null;
}
}; private ICountService countService; /** Called when the activity is first created.*/ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main); this.bindService(new Intent(“com.easymorse.CountService”), this.serviceConnection, BIND_AUTO_CREATE);
}
@Override protectedvoid onDestroy() {
this.unbindService(serviceConnection);
super.onDestroy(); //注意先后 }
}
编写传递基本型数据的远程服务
上面的示例,可以扩展为,让其他应用程序复用该服务。这样的服务叫远程(remote)服务,实际上是进程间通信(RPC)。
这时需要使用android接口描述语言(AIDL)来定义远程服务的接口,而不是上述那样简单的java接口。扩展名为aidl而不是java。可用上面的ICountService改动而成ICountSerivde.aidl,eclipse会自动生成相关的java文件。
package com.easymorse;
interface ICountService { int getCount();
}
编写服务(Service)类,稍有差别,主要在binder是通过远程获得的,需要通过桩(Stub)来获取。桩对象是远程对象的本地代理。
package com.easymorse;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;public class CountService extends Service { privateboolean threadDisable; privateint count; private ICountService.Stub serviceBinder= new ICountService.Stub() {
@Override publicint getCount()throws RemoteException { return count;
}
};
@Override public IBinder onBind(Intent intent) { return serviceBinder;
}
@Override public void onCreate() { super.onCreate(); new Thread(new Runnable() {
@Override publicvoid run() { while (!threadDisable) { try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
count++;
Log.v(“CountService”,"Count is " + count);
}
}
}).start();
}
@Override public void onDestroy() { super.onDestroy(); this.threadDisable= true;
Log.v(“CountService”,“on destroy”);
}
}
配置文件AndroidManifest.xml和上面的类似,没有区别。
在Activity中使用服务的差别不大,只需要对ServiceConnection中的调用远程服务的方法时,要捕获异常。
private ServiceConnection serviceConnection= new ServiceConnection() {
@Override public void onServiceConnected(ComponentName name, IBinder service) {
countService = (ICountService) service; try {
Log.v(“CountService”,“on serivce connected, count is” + countService.getCount());
} catch (RemoteException e) { thrownew RuntimeException(e);
}
}
@Override public void onServiceDisconnected(ComponentName name) {
countService =null;
}
};
这样就可以在同一个应用程序中使用远程服务的方式和自己定义的服务交互了。
如果是另外的应用程序使用远程服务,需要做的是复制上面的aidl文件和相应的包构到应用程序中,其他调用等都一样。
编写传递复杂数据类型的远程服务
远程服务往往不只是传递java基本数据类型。这时需要注意android的一些限制和规定:
-
android支持String和CharSequence
-
如果需要在aidl中使用其他aidl接口类型,需要import,即使是在相同包结构下;
-
android允许传递实现Parcelable接口的类,需要import;
-
android支持集合接口类型List和Map,但是有一些限制,元素必须是基本型或者上述三种情况,不需要import集合接口类,但是需要对元素涉及到的类型import;
-
非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。
这里将前面的例子中返回的int数据改为复杂数据类型:
package com.easymorse;import android.os.Parcel;import android.os.Parcelable;public class CountBean implements Parcelable { public static final Parcelable.Creator<CountBean> CREATOR = new Creator<CountBean>() {
@Override public CountBean createFromParcel(Parcel source) {
CountBean bean =new CountBean();
bean.count = source.readInt(); return bean;
}
@Override public CountBean[] newArray(int size) { returnnew CountBean[size];
}
}; public int count;
@Override public void writeToParcel(Parcel dest,int flags) {
dest.writeInt(this.count);
}
@Override public int describeContents() { return0;
}
}
然后,需要在相同包下建一个同名的aidl文件,用于android生成相应的辅助文件:
package com.easymorse;
parcelable CountBean;
这一步是android 1.5后的变化,无法通过adt生成aidl,也不能用一个比如全局的project.aidl文件,具体见:
然后,需要在服务的aidl文件中修改如下:
package com.easymorse;import com.easymorse.CountBean;interface ICountService {
CountBean getCount();
}
其他的改动很小,只需将CountService和调用CountService的部分修改为使用CountBean即可
最后
其实要轻松掌握很简单,要点就两个:
- 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
- 多练。 (视频优势是互动感强,容易集中注意力)
你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。
阿里P7Android高级教程
下面资料部分截图,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。
附送高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、近期面试跳槽、自身职业规划迷茫的朋友们。
Android核心高级技术PDF资料,BAT大厂面试真题解析;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
34)]
附送高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、近期面试跳槽、自身职业规划迷茫的朋友们。
Android核心高级技术PDF资料,BAT大厂面试真题解析;
[外链图片转存中…(img-E1VZhKl0-1713714686334)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-52NIyHZb-1713714686335)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!