《Android Studio开发实战 从零基础到App上线(第2版)》常见问题解答

下面是第二版读者较经常提出的问题,现统一整理回复如下:

1、第1章的SVN仓库地址

问题:第17页“1.5.2 安装SVN工具”这节里面提到的SVN仓库地址要填什么?
回答:SVN仓库地址指的是SVN服务器地址,如果你们单位有专人负责svn代码管理,可向他(svn管理员)咨询这个svn地址。如果你的代码只在自己电脑运行,不需要提交给服务器备份,那么建议略过svn这部分。

2、第2章的跑马灯文字滚不起来

问题:第34页“2.3.1 文本视图TextView”中的“1. 跑马灯效果”,按照示例XML编写了布局文件,结果跑马灯文字还是跑不起来,点击也不管用。
回答:该例子除了xml格式的布局文件,还需java代码配合才行,搭配用的java文件参见本书附录源码junior模块里的MarqueeActivity.java,完整的文件路径见下:
        junior\src\main\java\com\example\junior\MarqueeActivity.java
另外,如果发现TextView被点击后,跑马灯不会自动暂停的话,需要开发者给TextView注册一个点击监听器,然后重写点击监听器的onClick方法,在该方法中编写暂停跑马灯的处理代码。具体代码参见刚才说的MarqueeActivity.java。

3、第10章根据经纬度获取不到地址

问题:第430页“10.2.3 HTTP接口调用”中的实战小项目,根据经纬度调用Google Map获取不到地址信息。
回答:谷歌地图从2019年开始必须传入密钥才能根据经纬度获取地址,所以现在无法正常调用Google Map的地址查询接口了。解决办法是把查询接口改成国内的天地图,涉及到network模块的GetAddressTask.java,有三处地方要改:
第一处修改mAddressUrl,代码示例如下:

        private String mAddressUrl = "https://api.tianditu.gov.cn/geocoder?postStr={'lon':%f,'lat':%f,'ver':1}&type=geocode&tk=145897399844a50e3de2309513c8df4b";

第二处doInBackground方法里面拼接url的代码改成下面这样:

        String url = String.format(mAddressUrl, location.getLongitude(), location.getLatitude());

第三处从json串解析地址信息的代码修改如下:

                JSONObject obj = new JSONObject(resp_data.content);
                JSONObject result = obj.getJSONObject("result");
                address = result.getString("formatted_address");

已经改好的GetAddressTask.java代码例子见如下页面:
        https://github.com/aqi00/android2/blob/master/network/src/main/java/com/example/network/task/GetAddressTask.java

4、第10章的仿QQ聊天,客户端与服务端无法通信

回答:网络部分的附录代码分成两块,客户端代码在network模块,服务端代码包括NetServer工程和SocketServer工程,其中NetServer工程承担HTTP服务器的角色,SocketServer承担Socket服务器的角色,这两种服务器都要在电脑上启动。客户端与服务端无法通信的原因可能有以下几点:
1、network模块中ClientThread.java里面的SOCKET_IP没有改成Socket服务器的ip,如果SocketServer工程在笔记本电脑上启动的话,SOCKET_IP就填笔记本电脑的无线ip
2、network模块中ClientThread.java里面REQUEST_URL没有改成HTTP服务器的ip,如果NetServer工程在笔记本电脑上启动的话,REQUEST_URL里的ip就填笔记本电脑的无线ip
3、network模块中QueryFriendTask.java里面mQueryUrl的"/queryFriend"被改成大写的"/QueryFriend"了,注意这里的q是小写的。
特别注意,在cmd窗口下,使用命令“ipconfig /all”要找的是笔记本电脑的无线ip,不是找网线的有线ip。如果在笔记本电脑上启动模拟器充当客户端,代码里的服务器ip也必须填笔记本电脑的无线ip,不能填127.0.0.1
 

5、第10章的HTTP接口调用,出现错误“No Network Security Config specified”

回答:Android9开始默认使用加密连接,也就是只能访问https打头的网络地址,不能访问http打头的网络地址(如果访问http地址就会报错“No Network Security Config specified”)。此时要在network模块的res目录下面创建xml目录,并在xml目录下新建文件network_security_config.xml,文件内容如下所示:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

然后打开network模块的AndroidManifest.xml,在该文件的application节点下增加android:networkSecurityConfig属性,也就是下面这样:

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:networkSecurityConfig="@xml/network_security_config"
        android:name=".MainApplication">

配置完毕重新运行network模块,就能访问http打头的地址了。
其它无法访问网络图片、无法打开网页、无法下载APK等问题,均可照此办理。或者直接把http换成https也行。


6、使用Tomcat8.5无法运行第10章的服务端工程NetServer

回答:针对tomcat8.5需要对NetServer工程做以下修改:
1、打开NetServer\.settings\org.eclipse.wst.common.project.facet.core.xml,把里面的“Apache Tomcat v8.0”改为“Apache Tomcat v8.5”
2、在eclipse中右击NetServer,依次选择菜单“Build Path”——“Configure Build Path”,窗口右边切到Library页,选中带红叉的“Apache Tomcat v8.0”,再单击右边的Remove按钮移除8.0;然后单击右边的Add Library按钮,在弹窗中选择“Server Runtime”,单击Next按钮,在下一页选中Apache Tomcat v8.5,然后单击Finish按钮。
3、在eclipse中右击NetServer,依次选择菜单“Build Path”——“Configure Build Path”,窗口右边切到Library页,选中带红叉的“JRE System Library***”,再单击右边的Remove按钮移除该jdk;然后单击右边的Add Library按钮,在弹窗中选择“JRE System Library”,单击Next按钮,在下一页选中本地的jdk,然后单击Finish按钮。
4、打开NetServer\WebRoot\upload.jsp,把“http://192.168.0.212:8080/UploadTest/uploadServlet”改为“http://localhost:8080/NetServer/uploadServlet”(注意端口号要填正确)
5、打开NetServer\src\servlet\UploadServlet.java,把下面这行
    String filePath = String.format("%s../../%s", rootPath, fileName);
改为下面这样:
    String filePath = String.format("D:/%s", fileName);
最后重新启动elipse,再运行NetServer


7、第10章的Socket通信源码在发送消息时报错“System.err: android.os.NetworkOnMainThreadException”

回答:需要把MessageTransmit.java里的下面这行代码
    mWriter.write(send_msg.getBytes("utf8"));
改成以下代码:

    // 即使在Handler中访问网络,也要开启分线程来操作
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                // 往输出流对象中写入数据
                mWriter.write(send_msg.getBytes("utf8"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

或者把mSendHandler的赋值语句放到MessageTransmit类的run方法之中,确保mSendHandler的代码在分线程中运行。

更多问题可加入QQ群进行咨询,群号是493199768

发布了226 篇原创文章 · 获赞 669 · 访问量 97万+

猜你喜欢

转载自blog.csdn.net/aqi00/article/details/87122804
今日推荐