Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android 练手之旅——PhotoHunter(一) #3

Open
soapgu opened this issue Feb 22, 2021 · 0 comments
Open

Android 练手之旅——PhotoHunter(一) #3

soapgu opened this issue Feb 22, 2021 · 0 comments
Labels
Demo Demo 安卓 安卓

Comments

@soapgu
Copy link
Owner

soapgu commented Feb 22, 2021

这次安卓学习主要是以练手项目结合来实现。
先制定下第一阶段功能目标

  1. 能随机获取一张图片以及图片相关信息
  2. 能展示图片以及信息
  3. 点击一下按钮能更换一张新的图片
  4. 尝试支持横屏竖屏不同的布局切换

使用okhttp,gson,logger

仓库地址

最基本的功能已经完成了,样子有点小丑。。。
图片

首先需要在AndroidManifes.xml里面声明权限

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

注意,如果不声明运行程序直接崩溃,并报无访问internet权限。原来还想加存储读写权限的,后来发现没有必要。

定义好json反序列化对象

public class Photo {
    public String id;
    public int width;
    public int height;
    public String alt_description;
    public PhotoUrl urls;
}

public class PhotoUrl {
    public String small;
}

这里和C#的json实体类有点小区别,只要定义好feild就行而不是用property

声明好Http Client对象,这里文档建议共享实例,如果在一个程序中,可以最大节约和复用资源
private OkHttpClient client = new OkHttpClient();

1 就是获取unsplash api获取随机照片的api的调用
2 解析api返回的json,填充图片说明 并下载小图
3 把小图生成bitmap对象并赋值给ImageView

接下来是主要代码,有点丑

this.findViewById(R.id.new_button).setOnClickListener( v ->{
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .build();
            Call call = this.client.newCall(request);

            call.enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    Logger.e("Get Photo Error:%s" , e.getMessage());
                    runOnUiThread(() -> textView.setText("Error for Hunter Photo"));
                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    Logger.i("Response Code:%s",response.code());
                    if( response.isSuccessful() ) {
                        Logger.i("Success fetch photo information , Thread:%s" , Thread.currentThread().getId());
                        Gson gson = new Gson();
                        ResponseBody responseBody = response.body();
                        if( responseBody != null ) {
                            Photo photo = gson.fromJson(responseBody.string(), Photo.class);
                            response.close();
                            runOnUiThread(() -> textView.setText(photo.alt_description));

                            Request imageRequest = new Request.Builder()
                                    .url(photo.urls.small)
                                    .get()
                                    .build();
                            Call downloadCall = client.newCall(imageRequest);
                            downloadCall.enqueue(new Callback() {
                                @Override
                                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                                    Logger.e("download image Error:%s", e.getMessage());
                                }

                                @Override
                                public void onResponse(@NotNull Call call, @NotNull Response response) {
                                    if (response.isSuccessful()) {
                                        Logger.i("Success response  photo image resource , Thread:%s" , Thread.currentThread().getId());
                                        ResponseBody downloadBody = response.body();
                                        if (downloadBody != null) {
                                            InputStream inputStream = downloadBody.byteStream();
                                            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                                            response.close();
                                            runOnUiThread(() -> photoView.setImageBitmap(bitmap));
                                        }
                                    }
                                }
                            });
                        }
                    }
                }
            });

1 调用两个GET的请求用的是Callback回调,回调嵌套回调代码看着有点点不适。有点像node的回调回调。这里就有点怀念有协程的时代,还是有 asycn await 的时候比较香。以后再看看怎么能改善这块代码的写法
2 前面嵌套回调的副作用,回调类的方法有throws IOException,第二个回调里面再加就出警告了。只能去掉一个,这个也只能后面填坑了
3 Trace了下OKHttp调用的线程

2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ Thread: OkHttp https://api.unsplash.com/...
2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ RealCall$AsyncCall.run  (RealCall.kt:519)
2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: │    MainActivity$1.onResponse  (MainActivity.java:58)
2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ Response Code:200
2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:44.433 29975-30022/com.soapdemo.photohunter I/SoapAPP: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:44.434 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ Thread: OkHttp https://api.unsplash.com/...
2021-02-24 10:57:44.434 29975-30022/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:44.434 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ RealCall$AsyncCall.run  (RealCall.kt:519)
2021-02-24 10:57:44.434 29975-30022/com.soapdemo.photohunter I/SoapAPP: │    MainActivity$1.onResponse  (MainActivity.java:60)
2021-02-24 10:57:44.434 29975-30022/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:44.434 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ Success fetch photo information , Thread:1551
2021-02-24 10:57:44.434 29975-30022/com.soapdemo.photohunter I/SoapAPP: └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:44.636 29975-30031/com.soapdemo.photohunter I/SoapAPP: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:44.636 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ Thread: OkHttp https://images.unsplash.com/...
2021-02-24 10:57:44.636 29975-30031/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:44.636 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ RealCall$AsyncCall.run  (RealCall.kt:519)
2021-02-24 10:57:44.636 29975-30031/com.soapdemo.photohunter I/SoapAPP: │    MainActivity$1$1.onResponse  (MainActivity.java:80)
2021-02-24 10:57:44.636 29975-30031/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:44.636 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ Success response  photo image resource , Thread:1558
2021-02-24 10:57:44.636 29975-30031/com.soapdemo.photohunter I/SoapAPP: └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ Thread: OkHttp https://api.unsplash.com/...
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ RealCall$AsyncCall.run  (RealCall.kt:519)
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: │    MainActivity$1.onResponse  (MainActivity.java:58)
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ Response Code:200
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:46.791 29975-30031/com.soapdemo.photohunter I/SoapAPP: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:46.792 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ Thread: OkHttp https://api.unsplash.com/...
2021-02-24 10:57:46.792 29975-30031/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:46.792 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ RealCall$AsyncCall.run  (RealCall.kt:519)
2021-02-24 10:57:46.792 29975-30031/com.soapdemo.photohunter I/SoapAPP: │    MainActivity$1.onResponse  (MainActivity.java:60)
2021-02-24 10:57:46.792 29975-30031/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:46.792 29975-30031/com.soapdemo.photohunter I/SoapAPP: │ Success fetch photo information , Thread:1558
2021-02-24 10:57:46.792 29975-30031/com.soapdemo.photohunter I/SoapAPP: └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:46.835 29975-30022/com.soapdemo.photohunter I/SoapAPP: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2021-02-24 10:57:46.836 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ Thread: OkHttp https://images.unsplash.com/...
2021-02-24 10:57:46.836 29975-30022/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:46.836 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ RealCall$AsyncCall.run  (RealCall.kt:519)
2021-02-24 10:57:46.836 29975-30022/com.soapdemo.photohunter I/SoapAPP: │    MainActivity$1$1.onResponse  (MainActivity.java:80)
2021-02-24 10:57:46.836 29975-30022/com.soapdemo.photohunter I/SoapAPP: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2021-02-24 10:57:46.836 29975-30022/com.soapdemo.photohunter I/SoapAPP: │ Success response  photo image resource , Thread:1551
2021-02-24 10:57:46.836 29975-30022/com.soapdemo.photohunter I/SoapAPP: └────────────────────────────────────────────────────────────────────────────────────────────────────────────────

观察下来OKHttpClient的Socket应该是多路复用的,显然两个线程是分别管了两个baseUrl
Thread 1558 负责 https://api.unsplash.com/...
Thread 1551 负责 https://images.unsplash.com/...
分别点击了2次按钮分别执行了2个HTTP请求,一共是4个, 两个Thread都没有被释放。多路复用名副其实

4 关于Response和ResponseBody
一定要Close一定要Close一定要Close,要内存泄漏哦。有点奇怪这么重要的事情,为啥官挡没在显眼位置指出。
图片

最后把默认安卓机器人的图标按教程改下,下次再改一个酷一点了,已经装到手机里面,明天一早可以去骗小朋友去了~~~

参考链接
CodeLab
Change the app icon
Add images to your Android app
OKHTTP
官档入口
Okhttp3基本使用
gson
github地址

(未完待续,后面完善部分另开篇)

@soapgu soapgu added Demo Demo 安卓 安卓 labels Feb 23, 2021
@soapgu soapgu changed the title Android 练手之旅——PhotoHunter Android 练手之旅——PhotoHunter(一) Feb 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Demo Demo 安卓 安卓
Projects
None yet
Development

No branches or pull requests

1 participant