Intent.putExtra()传递Object对象或者ArrayList<Object>

本文介绍如何使用Android的Intent来传递复杂的数据类型,包括Object对象和ArrayList&lt;Object&gt;对象。详细讲解了实现Serializable和Parcelable接口的方法,并给出了具体的代码实例。

FBI Warning:欢迎转载,但请标明出处:http://blog.youkuaiyun.com/codezjx/article/details/8876753,未经本人同意请勿用于商业用途,感谢支持!


Intent传递基本类型相信大家都十分熟悉,如何传递Object对象或者ArrayList<Object>对象呢?

可以通过:

(1)public Intent putExtra (String name, Serializable value)

(2)public Intent putExtra (String name, Parcelable value)

       public Intent putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value)


一、通过实现Serializable接口传递

(1)首先让Person继承Serializable接口

package com.example.hellojni;

import java.io.Serializable;

public class Person implements Serializable{

	/**
	 * Auto generate
	 */
	private static final long serialVersionUID = -5053412967314724078L;

	private String name;
	
	private int age;
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
}

(2)通过Intent来进行传输,具体方法是:public Intent putExtra (String name, Serializable value)

        Intent intent = new Intent(this, OtherActivity.class);
        intent.putExtra("person", new Person("bear", 22));
        startActivity(intent);


(3)另外一个Activity中打印值:

	Intent intent = getIntent();
	Person person = (Person)intent.getSerializableExtra("person");
	System.out.println("name:" + person.getName());
	System.out.println("age:" + person.getAge());


(4)传递ArrayList<Person>:

        Intent intent = new Intent(this, OtherActivity.class);
    	ArrayList<Person> personList= new ArrayList<Person>();
    	initList(personList);  //初始化personList
        intent.putExtra("personList", personList);
        startActivity(intent);

注意传值类型必须是ArrayList而不能是List。调用的还是public Intent putExtra (String name, Serializable value)这个函数,另外一边获取的时候强制转化为 ArrayList<Person>即可)



二、通过实现Parcelable接口传递

同上,Person类实现Parcelable接口即可:


传递Object用:public Intent putExtra (String name, Parcelable value)
传递ArrayList<Object>用:public Intent putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value)


(同是序列化的接口,为神马Parcelable分开提供了2个函数,而传Serializable只提供了一个?这里我也很不解。。。)


你没给我提供MapFragment和SearchResultActivity和activity_route_plan.xml修改后的完整代码,这几个也是最小量修改即可。MapFragment原代码如下:package com.example.bus.ui.map; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import com.amap.api.maps.MapView; import com.amap.api.maps.AMap; import com.amap.api.maps.model.LatLng; //import com.example.bus.R; //import com.example.bus.databinding.FragmentMapBinding; import com.amap.api.services.core.AMapException; import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.UiSettings; import com.amap.api.services.poisearch.PoiResult; import com.amap.api.services.poisearch.PoiSearch; import com.example.bus.R; import com.example.bus.RoutePlanActivity; import com.example.bus.databinding.FragmentMapBinding; import com.amap.api.services.core.PoiItem; import com.amap.api.services.core.LatLonPoint; // MapView 已在 XML 中声明,无需额外 import(会自动识别) public class MapFragment extends Fragment { private FragmentMapBinding binding; private MapView mapView; // 高德地图视图 private AMap aMap; // 地图控制器 private boolean isFirstLocationSet = false; // 防止反复跳转 @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 初始化 ViewModel 和 ViewBinding binding = FragmentMapBinding.inflate(inflater, container, false); View root = binding.getRoot(); //绑定 MapView mapView = root.findViewById(R.id.map_view); mapView.onCreate(savedInstanceState); // 必须调用生命周期方法 // 初始化地图 initMap(); if (binding.mapSearch != null) { binding.mapSearch.setOnClickListener(v -> { String keyword = binding.mapInput2.getText().toString().trim(); if (keyword.isEmpty()) { Toast.makeText(requireContext(), "请输入终点", Toast.LENGTH_SHORT).show(); return; } PoiSearch.Query query = new PoiSearch.Query(keyword, "", "全国"); query.setPageSize(10); // 可选:设置每页数量 query.setPageNum(0); // 可选:第一页 try { PoiSearch search = new PoiSearch(requireContext(), query); search.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() { @Override public void onPoiSearched(PoiResult result, int rCode) { requireActivity().runOnUiThread(() -> { if (rCode == 1000 && result != null && !result.getPois().isEmpty()) { PoiItem item = result.getPois().get(0); LatLonPoint point = item.getLatLonPoint(); Intent intent = new Intent(requireContext(), RoutePlanActivity.class); intent.putExtra("start_mode", "my_location"); intent.putExtra("target_lat", point.getLatitude()); intent.putExtra("target_lng", point.getLongitude()); intent.putExtra("target_title", item.getTitle()); startActivity(intent); } else { handlePoiSearchError(rCode); } }); } @Override public void onPoiItemSearched(PoiItem item, int rCode) { // 不使用单个 POI 搜索 } }); // 发起异步请求(这个方法不会再抛异常了) search.searchPOIAsyn(); } catch (AMapException e) { e.printStackTrace(); Toast.makeText(requireContext(), "POI搜索初始化失败:" + e.getMessage(), Toast.LENGTH_LONG).show(); } }); } return root; } private void handlePoiSearchError(int rCode) { String errorMsg; switch (rCode) { case 1101: errorMsg = "网络连接异常"; break; case 1102: errorMsg = "网络响应超时"; break; case 1103: errorMsg = "解析异常"; break; case 1104: errorMsg = "请求参数非法"; break; case 1200: errorMsg = "API Key 不存在"; break; case 1202: errorMsg = "签名验证失败(SHA1/包名不匹配)"; break; case 1206: errorMsg = "API Key 权限不足(未开通 POI 搜索服务)"; break; default: errorMsg = "未知错误: " + rCode; break; } Toast.makeText(requireContext(), "搜索失败: " + errorMsg, Toast.LENGTH_LONG).show(); } /** * 初始化地图 */ private void initMap() { if (aMap == null) { aMap = mapView.getMap(); UiSettings uiSettings = aMap.getUiSettings(); uiSettings.setZoomControlsEnabled(true); // 显示缩放按钮 uiSettings.setCompassEnabled(true); // 显示指南针 uiSettings.setMyLocationButtonEnabled(false); // 我们自己控制定位行为 } } @Override public void onResume() { super.onResume(); //每次恢复可见时都检查权限状态 mapView.onResume(); // ✅ 直接开启定位图层(信任 MainActivity 的判断) if (aMap != null) { aMap.setMyLocationEnabled(true); // 只第一次进入时移动相机 if (!isFirstLocationSet) { LatLng defaultLoc = new LatLng(39.909186, 116.397411); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLoc, 12f)); isFirstLocationSet = true; } } } @Override public void onPause() { super.onPause(); mapView.onPause(); } @Override public void onDestroyView() { super.onDestroyView(); if (mapView != null) { mapView.onDestroy(); } binding = null; } @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } } SearchResultActivity原代码如下:package com.example.bus; import android.content.Intent; import android.os.Bundle; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.amap.api.maps.AMap; import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.MapView; import com.amap.api.maps.UiSettings; import com.amap.api.maps.model.LatLng; import com.amap.api.maps.model.Marker; import com.amap.api.maps.model.MarkerOptions; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.core.PoiItem; import com.amap.api.services.poisearch.PoiResult; import com.amap.api.services.poisearch.PoiSearch; import java.util.ArrayList; import java.util.List; public class SearchResultActivity extends AppCompatActivity implements PoiSearch.OnPoiSearchListener { private EditText searchInput; private Button searchBtn, goToBtn; private RecyclerView resultListView; private List<PoiItem> poiList = new ArrayList<>(); private ResultAdapter adapter; private PoiSearch poiSearch; // 地图相关 private MapView mapView; private AMap aMap; private Marker selectedMarker; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search_result); // 设置 ActionBar 返回按钮 if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setTitle("搜索地点"); } initViews(); setupMap(savedInstanceState); // 初始化地图 setupSearch(); // 初始化搜索 } private void initViews() { searchInput = findViewById(R.id.search_input); searchBtn = findViewById(R.id.search_btn); resultListView = findViewById(R.id.result_list); goToBtn = findViewById(R.id.btn_go_to); goToBtn.setEnabled(false); } private void setupMap(Bundle savedInstanceState) { mapView = findViewById(R.id.map_view); mapView.onCreate(savedInstanceState); if (aMap == null) { aMap = mapView.getMap(); UiSettings uiSettings = aMap.getUiSettings(); uiSettings.setZoomControlsEnabled(true); uiSettings.setCompassEnabled(true); uiSettings.setScrollGesturesEnabled(true); aMap.setOnMapClickListener(latLng -> { if (selectedMarker != null) selectedMarker.remove(); selectedMarker = aMap.addMarker(new MarkerOptions() .position(latLng) .title("选中位置")); goToBtn.setEnabled(true); }); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.909186, 116.397411), 10f)); } } private void setupSearch() { String keyword = getIntent().getStringExtra("keyword"); if (keyword != null && !keyword.isEmpty()) { searchInput.setText(keyword); performSearch(keyword); } searchBtn.setOnClickListener(v -> { String text = searchInput.getText().toString().trim(); if (!text.isEmpty()) { performSearch(text); } else { Toast.makeText(this, "请输入关键词", Toast.LENGTH_SHORT).show(); } }); goToBtn.setOnClickListener(v -> { if (selectedMarker != null) { LatLng pos = selectedMarker.getPosition(); navigateToRoute(pos.latitude, pos.longitude, "地图选点"); } else if (!poiList.isEmpty()) { PoiItem item = poiList.get(0); LatLonPoint p = item.getLatLonPoint(); navigateToRoute(p.getLatitude(), p.getLongitude(), item.getTitle()); } else { Toast.makeText(this, "暂无目标位置", Toast.LENGTH_SHORT).show(); } }); } private void navigateToRoute(double lat, double lng, String title) { Intent intent = new Intent(this, RoutePlanActivity.class); intent.putExtra("start_mode", "my_location"); intent.putExtra("target_lat", lat); intent.putExtra("target_lng", lng); intent.putExtra("target_title", title); startActivity(intent); } private void performSearch(String keyword) { PoiSearch.Query query; if (isLikelyBusStop(keyword)) { // 如果像公交站名,加过滤 query = new PoiSearch.Query(keyword, "15", "全国"); // 公共交通类 } else { // 否则不限类别,确保能搜到地标 query = new PoiSearch.Query(keyword, "", "全国"); } query.setPageSize(20); query.setPageNum(0); try { poiSearch = new PoiSearch(this, query); poiSearch.setOnPoiSearchListener(this); poiSearch.searchPOIAsyn(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "搜索启动失败", Toast.LENGTH_SHORT).show(); } } private boolean isLikelyBusStop(String keyword) { return keyword.contains("公交") || keyword.contains("地铁") || keyword.contains("BRT") || keyword.endsWith("站") || keyword.endsWith("场"); } @Override public void onPoiSearched(PoiResult result, int rCode) { if (rCode == 1000 && result != null && result.getPois() != null) { poiList.clear(); poiList.addAll(result.getPois()); if (adapter == null) { adapter = new ResultAdapter(poiList, item -> { if (selectedMarker != null) selectedMarker.remove(); LatLng latLng = new LatLng(item.getLatLonPoint().getLatitude(), item.getLatLonPoint().getLongitude()); selectedMarker = aMap.addMarker(new MarkerOptions().position(latLng).title(item.getTitle())); aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14f)); goToBtn.setEnabled(true); }); resultListView.setLayoutManager(new LinearLayoutManager(this)); resultListView.setAdapter(adapter); } else { adapter.notifyDataSetChanged(); } goToBtn.setEnabled(!poiList.isEmpty()); } else { String msg = rCode == 17 ? "高德Key校验失败" : "搜索失败: 错误码=" + rCode; Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } } @Override public void onPoiItemSearched(PoiItem item, int rCode) {} @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); if (poiSearch != null) poiSearch.setOnPoiSearchListener(null); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } @Override public boolean onSupportNavigateUp() { onBackPressed(); return true; } } 这两个你说要更改跳转的,还要activity_route_plan.xml代码如下:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:layout_marginTop="?attr/actionBarSize"> <!-- 地图区域(占上面 60%) --> <com.amap.api.maps.MapView android:id="@+id/map_view" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/recycler_steps" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHeight_percent="0.6" /> <!-- 步骤列表(下方 40%) --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_steps" android:layout_width="0dp" android:layout_height="0dp" android:background="#f5f5f5" android:elevation="4dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHeight_percent="0.4" /> </androidx.constraintlayout.widget.ConstraintLayout> 你来添加返回按钮(ActionBar),也是最小量修改,原框架别变
最新发布
11-15
你先别着急回答,刚刚给你提供的是最初的代码,后来,你给我提供过一些修改建议,我的HomeFragment修改成这样了,但是 binding.homeSearch.setOnClickListener(v -> { String keyword = binding.homeInput.getText().toString().trim(); if (keyword.isEmpty()) { Toast.makeText(requireContext(), "请输入关键词", Toast.LENGTH_SHORT).show(); return; } // ✅ 使用 MainActivity 的统一权限流程 MainActivity activity = (MainActivity) requireActivity(); activity.ensureFineLocationPermission(() -> { // ✅ 权限通过后再跳转 Intent intent = new Intent(requireContext(), SearchResultActivity.class); intent.putExtra("keyword", keyword); startActivity(intent); }); });这一段他报错Unreachable statement。MapFragment修改成这样了package com.example.bus.ui.map; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import com.amap.api.maps.MapView; import com.amap.api.maps.AMap; import com.amap.api.maps.model.LatLng; //import com.example.bus.R; //import com.example.bus.databinding.FragmentMapBinding; import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.UiSettings; import com.example.bus.R; import com.example.bus.RoutePlanActivity; import com.example.bus.databinding.FragmentMapBinding; // MapView 已在 XML 中声明,无需额外 import(会自动识别) public class MapFragment extends Fragment { private FragmentMapBinding binding; private MapView mapView; // 高德地图视图 private AMap aMap; // 地图控制器 private boolean isFirstLocationSet = false; // 防止反复跳转 @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 初始化 ViewModel 和 ViewBinding binding = FragmentMapBinding.inflate(inflater, container, false); View root = binding.getRoot(); //绑定 MapView mapView = root.findViewById(R.id.map_view); mapView.onCreate(savedInstanceState); // 必须调用生命周期方法 // 初始化地图 initMap(); if (binding.mapSearch != null) { binding.mapSearch.setOnClickListener(v -> { String keyword = binding.mapInput2.getText().toString().trim(); if (keyword.isEmpty()) { Toast.makeText(requireContext(), "请输入终点", Toast.LENGTH_SHORT).show(); return; } // ✅ 直接跳转路线页(不需要权限检查,因为能进此 Fragment 说明已有权限) Intent intent = new Intent(requireContext(), RoutePlanActivity.class); intent.putExtra("start_mode", "input"); // 表示从输入框获取起点 // TODO: 可提取 map_input1.getText() 作为起点坐标(需先搜索) intent.putExtra("target_lat", 0); // 暂空,实际应在搜索后填充 intent.putExtra("target_lng", 0); intent.putExtra("target_title", keyword); startActivity(intent); }); } return root; } /** * 初始化地图 */ private void initMap() { if (aMap == null) { aMap = mapView.getMap(); UiSettings uiSettings = aMap.getUiSettings(); uiSettings.setZoomControlsEnabled(true); // 显示缩放按钮 uiSettings.setCompassEnabled(true); // 显示指南针 uiSettings.setMyLocationButtonEnabled(false); // 我们自己控制定位行为 } } @Override public void onResume() { super.onResume(); //每次恢复可见时都检查权限状态 mapView.onResume(); // ✅ 直接开启定位图层(信任 MainActivity 的判断) if (aMap != null) { aMap.setMyLocationEnabled(true); // 只第一次进入时移动相机 if (!isFirstLocationSet) { LatLng defaultLoc = new LatLng(39.909186, 116.397411); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLoc, 12f)); isFirstLocationSet = true; } } } @Override public void onPause() { super.onPause(); mapView.onPause(); } @Override public void onDestroyView() { super.onDestroyView(); if (mapView != null) { mapView.onDestroy(); } binding = null; } @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } } 他是正常的没报错,后面ResultAdapter和SearchResultActivity都是import com.amap.api.services.poisearch.PoiItem;问题,RoutePlanActivity存在Class 'RoutePlanActivity' must either be declared abstract or implement abstract method 'onWalkRouteSearched(WalkRouteResult, int)' in 'OnRouteSearchListener'和Unhandled exception: com.amap.api.services.core.AMapException问题
11-04
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值