Android——Toast.makeText()

本文介绍了Android中Toast的作用及其使用方法。Toast是一种简单的消息提示框,用于短暂显示信息且不可交互。文章详细解释了Toast的三个参数:上下文环境、消息框内容及显示时间,并提供了示例代码。

  1.Toast 作用

    它是android中一种简单的消息提示框,它没有焦点(即不能被点击),会根据设置的时间自动消失。

  2.介绍下Toast的参数

  

1 Toast t = Toast.makeText(MainActivity.this, "哈哈哈", Toast.LENGTH_LONG);
2               t.show();

  第一个参数:当前的上下文环境,,Activity中我们直接用this代替,而到了一个button的onClick(View view)等方法时,我们用this时就会报错,改用ActivityName.this(上面MainActivity.this),                           主要原因是因为现Context的类主要有Android特有的几个模型,Activity、Service以及BroadcastReceiver。

  第二个参数:消息框的内容;

  第三个参数:显示的时间;

 

更多效果详情请参照:http://daikainan.iteye.com/blog/1405575;

 

转载于:https://www.cnblogs.com/mark0812/p/6075265.html

我想我暂时先不更改吧,因为我还有最后一步没做,就是规划路线。我能够搜索到地点,但是用户点击到这去之后,项目就闪退了,肯定就是RoutePlanActivity的问题,代码如下:package com.example.bus; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.amap.api.maps.AMap; import com.amap.api.maps.MapView; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.route.BusPath; import com.amap.api.services.route.BusRouteResult; import com.amap.api.services.route.DriveRouteResult; import com.amap.api.services.route.RideRouteResult; import com.amap.api.services.route.RouteResult; import com.amap.api.services.route.RouteSearch; import com.amap.api.services.route.WalkRouteResult; public class RoutePlanActivity extends AppCompatActivity implements RouteSearch.OnRouteSearchListener { private static final String TAG = "RoutePlanActivity"; private MapView mapView; private AMap aMap; private RouteSearch routeSearch; private Handler mainHandler = new Handler(Looper.getMainLooper()); // 防止重复请求 private boolean isSearching = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_route_plan); mapView = findViewById(R.id.map_view); mapView.onCreate(savedInstanceState); if (aMap == null) { aMap = mapView.getMap(); } try { // 初始化 RouteSearch(建议放在 Application 中全局复用) routeSearch = new RouteSearch(this); routeSearch.setRouteSearchListener(this); } catch (Exception e) { Log.e(TAG, "路线服务初始化失败", e); Toast.makeText(this, "路线服务初始化失败,请检查依赖", Toast.LENGTH_LONG).show(); finish(); return; } parseIntentAndStartSearch(); } private void parseIntentAndStartSearch() { if (isSearching) { Toast.makeText(this, "正在查询中,请稍候...", Toast.LENGTH_SHORT).show(); return; } String startMode = getIntent().getStringExtra("start_mode"); double targetLat = getIntent().getDoubleExtra("target_lat", 0); double targetLng = getIntent().getDoubleExtra("target_lng", 0); if (targetLat == 0 || targetLng == 0) { Toast.makeText(this, "目标位置无效", Toast.LENGTH_SHORT).show(); finish(); return; } LatLonPoint startPoint, targetPoint; if ("my_location".equals(startMode)) { // TODO: 使用定位 SDK 获取真实位置 startPoint = new LatLonPoint(39.909186, 116.397411); // 北京 } else { double startLat = getIntent().getDoubleExtra("start_lat", 0); double startLng = getIntent().getDoubleExtra("start_lng", 0); if (startLat == 0 || startLng == 0) { Toast.makeText(this, "起点位置无效", Toast.LENGTH_SHORT).show(); finish(); return; } startPoint = new LatLonPoint(startLat, startLng); } targetPoint = new LatLonPoint(targetLat, targetLng); RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(startPoint, targetPoint); RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery(fromAndTo, RouteSearch.BUS_DEFAULT, "北京", 0); try { isSearching = true; showLoading(); // 显示加载动画 routeSearch.calculateBusRouteAsyn(query); } catch (Exception e) { Log.e(TAG, "启动公交路线查询失败", e); hideLoading(); Toast.makeText(this, "路线查询启动失败", Toast.LENGTH_SHORT).show(); } } @Override public void onBusRouteSearched(BusRouteResult result, int rCode) { isSearching = false; hideLoading(); if (rCode != 1000) { handleSearchError(rCode); return; } if (result == null || result.getPaths() == null || result.getPaths().isEmpty()) { Toast.makeText(this, "未找到公交路线", Toast.LENGTH_SHORT).show(); return; } // ✅ 关键优化:将耗时操作延后或放子线程(如绘制) BusPath bestPath = result.getPaths().get(0); String duration = formatDuration(bestPath.getDuration()); String walkDistance = bestPath.getWalkDistance() + "米步行"; // ✅ 使用 Handler.post 确保轻量更新 UI mainHandler.post(() -> { Toast.makeText(RoutePlanActivity.this, "推荐路线:" + duration + "," + walkDistance, Toast.LENGTH_LONG).show(); // TODO: 此处可添加路线绘制(建议封装成独立方法并加限制) // drawRouteOnMap(bestPath); }); } private void handleSearchError(int rCode) { String errorMsg; switch (rCode) { case 1001: errorMsg = "参数错误"; break; case 1002: errorMsg = "Key 错误"; break; case 1003: errorMsg = "网络错误"; break; case 1004: errorMsg = "其他错误"; break; default: errorMsg = "错误码: " + rCode; } Toast.makeText(this, "查询失败:" + errorMsg, Toast.LENGTH_LONG).show(); } private String formatDuration(long seconds) { long minutes = seconds / 60; if (minutes > 0) return minutes + "分钟"; return (seconds > 0 ? 1 : 0) + "分钟"; } private void showLoading() { // 如果有 ProgressBar 就显示它 // progressBar.setVisibility(View.VISIBLE); } private void hideLoading() { // progressBar.setVisibility(View.GONE); } // --- 其他回调空实现 --- @Override public void onDriveRouteSearched(DriveRouteResult result, int rCode) {} @Override public void onWalkRouteSearched(WalkRouteResult result, int rCode) {} @Override public void onRideRouteSearched(RideRouteResult result, int rCode) {} // ---------------- 生命周期方法 ---------------- @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { if (mapView != null) { mapView.onDestroy(); } if (routeSearch != null) { routeSearch.setRouteSearchListener(null); // 避免内存泄漏 } super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } }
最新发布
11-08
你已经把 `RoutePlanActivity` 的代码写得非常清晰、结构良好,而且也做了异常捕获和防重复请求。但你说: > **“用户点击‘到这去’后,项目闪退”** 我们来一步步排查这个问题。 --- ## 🔍 一、核心问题定位:**闪退 = 崩溃 = Crash** 我们需要知道: > ❓ 是不是因为 `Intent` 数据没传对? > ❓ 还是 `routeSearch` 初始化失败? > ❓ 或者是 SDK 缺少依赖? --- ## ✅ Step 1:确认崩溃日志(最关键) 请打开 **Logcat**,在 Android Studio 底部找到 `Logcat` 窗口,过滤你的应用包名(如 `com.example.bus`),然后复现操作(点“到这去”)。 查看是否有类似以下错误: ``` java.lang.NullPointerException: Attempt to invoke virtual method '...' at com.example.bus.RoutePlanActivity.parseIntentAndStartSearch(RoutePlanActivity.java:xx) ``` 或者: ``` Caused by: java.lang.ClassNotFoundException: Didn't find class "com.amap.api.services.route.RouteSearch" ``` 但我们先不依赖日志,直接从代码中找出最可能的几个致命点。 --- ## 🚨 高危问题 1:**城市名写死为“北京”,但目标地点可能不在北京** 你在创建公交路线查询时写了: ```java RouteSearch.BusRouteQuery query = new BusRouteQuery(fromAndTo, RouteSearch.BUS_DEFAULT, "北京", 0); ↑↑↑↑↑↑↑↑↑↑↑ ``` ⚠️ **这是大问题!** 如果你的目标地点是“上海外滩”,起点是“北京西站”,那么高德服务器会因为城市不匹配导致返回空结果或报错! ### ✅ 正确做法:动态获取城市名 你可以通过逆地理编码(ReGeocode)获取目标点所在城市,但现在为了最小修改,建议改为使用 `"全国"` 搜索: ```java // 修改这一行: RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery( fromAndTo, RouteSearch.BUS_DEFAULT, "全国", // ← 改成 "全国",支持跨城查询 0 ); ``` > ⚠️ 注意:高德 SDK 中 `"全国"` 是合法的城市参数,表示不限定城市范围。 ✅ 推荐改成 `"全国"` 先测试是否解决 crash。 --- ## 🚨 高危问题 2:**没有检查 intent 是否包含必要数据** 虽然你做了判断: ```java double targetLat = getIntent().getDoubleExtra("target_lat", 0); double targetLng = getIntent().getDoubleExtra("target_lng", 0); if (targetLat == 0 || targetLng == 0) { Toast.makeText(this, "目标位置无效", Toast.LENGTH_SHORT).show(); finish(); return; } ``` 但是注意:**纬度经度刚好是 `(0, 0)` 是赤道和本初子午线交点(大西洋中部),虽然是个有效坐标,但在地球上基本不可能是你想要的目的地。** 所以这个判断逻辑是对的。 但更安全的方式是用一个布尔标记传递是否有效: ### ✅ 改进建议(非必须,但推荐): 在 `SearchResultActivity` 跳转前这样传: ```java intent.putExtra("has_target", true); intent.putExtra("target_lat", lat); intent.putExtra("target_lng", lng); ``` 然后在 `RoutePlanActivity` 判断: ```java if (!getIntent().getBooleanExtra("has_target", false)) { Toast.makeText(this, "缺少目标位置", Toast.LENGTH_SHORT).show(); finish(); return; } ``` 不过目前先保留原逻辑。 --- ## 🚨 高危问题 3:**SDK 权限或混淆配置缺失(导致 RouteSearch 类找不到)** 如果 Logcat 出现: ``` java.lang.NoClassDefFoundError: Failed resolution of: Lcom/amap/api/services/route/RouteSearch; ``` 说明:**你没有正确引入 AMap Route SDK 或被 ProGuard 删除了。** ### ✅ 解决方法: #### ① 确认 `build.gradle` 添加了路线搜索依赖 ```gradle dependencies { implementation 'com.amap.api:map-2d:latestVersion' implementation 'com.amap.api:search:latestVersion' // 包含路线规划 } ``` 📌 注意:`search` 包含了 `RouteSearch` 功能,不要只引 `map-2d`。 ✅ 推荐版本(稳定): ```gradle implementation 'com.amap.api:map-2d:8.5.0' implementation 'com.amap.api:search:8.5.0' ``` 同步后 Clean & Rebuild。 #### ② 检查 `proguard-rules.pro`(上线才需要) ```pro -keep class com.amap.api.** {*;} -keep class com.autonavi.** {*;} -dontwarn com.amap.api.** ``` --- ## 🚨 高危问题 4:**主线程 Toast 更新用了 mainHandler.post —— 多余且可能导致 Context 泄漏?** 你写了: ```java mainHandler.post(() -> { Toast.makeText(RoutePlanActivity.this, "推荐路线:" + duration + "," + walkDistance, Toast.LENGTH_LONG).show(); }); ``` 其实完全没必要,因为 `onBusRouteSearched` 本来就在主线程回调! > ✅ 高德 SDK 所有 `OnRouteSearchListener` 回调都在 UI 线程执行。 所以可以直接: ```java Toast.makeText(this, "推荐路线:" + duration + "," + walkDistance, Toast.LENGTH_LONG).show(); ``` 但这不会导致崩溃。 --- ## ✅ 最终修复建议(立即修改) ### ✅ 修改点 1:将 `"北京"` 改为 `"全国"` ```java RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery( fromAndTo, RouteSearch.BUS_DEFAULT, "全国", // ← 关键修改!避免城市限制导致无结果或崩溃 0 ); ``` --- ### ✅ 修改点 2:添加 try-catch 包裹 `calculateBusRouteAsyn` 即使文档说它是异步安全的,有些老版本 SDK 在参数非法时仍会抛出异常。 ```java try { isSearching = true; showLoading(); routeSearch.calculateBusRouteAsyn(query); // ← 可能因 query 构造错误崩溃 } catch (Exception e) { Log.e(TAG, "启动公交路线查询失败", e); hideLoading(); isSearching = false; Toast.makeText(this, "路线查询启动失败:" + e.getMessage(), Toast.LENGTH_LONG).show(); } ``` --- ### ✅ 修改点 3:打印日志确认 intent 数据是否正常 加一行 debug 日志: ```java Log.d(TAG, "解析 Intent: start_mode=" + startMode + ", target=("+targetLat+","+targetLng+")"); ``` 确保跳转时数据传进来了。 --- ## ✅ 测试流程建议 1. 在 `SearchResultActivity` 中选一个地点 2. 点击“到这去” 3. 查看 Logcat 输出: - 是否打印了上面的日志? - 是否出现 `ClassNotFoundException` / `NullPointerException`? 4. 如果看到: ``` Caused by: java.lang.IllegalArgumentException: city is null or empty ``` → 就证明是 **城市名为空或无效** 导致的崩溃! --- ## ✅ 总结:你现在应该怎么做? | 操作 | 是否必须 | |------|----------| | ✅ 把 `"北京"` 改成 `"全国"` | ✔️ 必须!很可能是主因 | | ✅ 给 `calculateBusRouteAsyn` 加 try-catch | ✔️ 必须!防止崩溃 | | ✅ 检查 `build.gradle` 是否引入 `search` SDK | ✔️ 必须! | | ✅ 清理缓存并重新运行 | ✔️ 推荐 | --- ## ✅ 示例修改后的 `parseIntentAndStartSearch()` 方法(最终版) ```java private void parseIntentAndStartSearch() { if (isSearching) { Toast.makeText(this, "正在查询中,请稍候...", Toast.LENGTH_SHORT).show(); return; } String startMode = getIntent().getStringExtra("start_mode"); double targetLat = getIntent().getDoubleExtra("target_lat", 0); double targetLng = getIntent().getDoubleExtra("target_lng", 0); Log.d(TAG, "开始解析路线请求: mode=" + startMode + ", target=(" + targetLat + "," + targetLng + ")"); if (targetLat == 0 || targetLng == 0) { Toast.makeText(this, "目标位置无效", Toast.LENGTH_SHORT).show(); finish(); return; } LatLonPoint startPoint, targetPoint; if ("my_location".equals(startMode)) { startPoint = new LatLonPoint(39.909186, 116.397411); // 模拟当前位置 } else { double startLat = getIntent().getDoubleExtra("start_lat", 0); double startLng = getIntent().getDoubleExtra("start_lng", 0); if (startLat == 0 || startLng == 0) { Toast.makeText(this, "起点位置无效", Toast.LENGTH_SHORT).show(); finish(); return; } startPoint = new LatLonPoint(startLat, startLng); } targetPoint = new LatLonPoint(targetLat, targetLng); RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(startPoint, targetPoint); RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery( fromAndTo, RouteSearch.BUS_DEFAULT, "全国", // ✅ 关键修复:不能限定死城市 0 ); try { isSearching = true; showLoading(); routeSearch.calculateBusRouteAsyn(query); } catch (Exception e) { Log.e(TAG, "调用 calculateBusRouteAsyn 失败", e); isSearching = false; hideLoading(); Toast.makeText(this, "路线查询启动失败:" + e.getMessage(), Toast.LENGTH_SHORT).show()); } } ``` --- ## ✅ 下一步建议 现在你应该: 1. 修改 `"北京"` → `"全国"` 2. 加上 try-catch 3. 运行 App 再试一次“到这去” 👉 如果不再闪退,并弹出 “未找到公交路线” 或显示提示 → 成功! 后续可以加上地图绘制路线功能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值