Service中传递自定义类的问题分析
来源:互联网 发布:java 线程怎么实线的 编辑:程序博客网 时间:2024/06/06 04:37
Service中传递自定义类的问题分析
这两天自学利用AIDL传递自定义类发现在Android studio中一直出现编译问题,两天时间寝食不安,吃东西还过敏。。哎。不过总算研究出来了,也是让人欣慰的一件事情。
问题描述:在路径,设置都没错误的情况下,Android studio中编译一直不能通过,总会出现同一个问题,然后aidl.exe 关闭退出:
Information:Gradle tasks [:app:assembleDebug]:app:preBuild UP-TO-DATE:app:preDebugBuild UP-TO-DATE:app:checkDebugManifest:app:preReleaseBuild UP-TO-DATE:app:prepareComAndroidSupportAppcompatV72221Library UP-TO-DATE:app:prepareComAndroidSupportSupportV42221Library UP-TO-DATE:app:prepareDebugDependencies:app:compileDebugAidlThis application has requested the Runtime to terminate it in an unusual way.Please contact the application's support team for more information.**terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_S_construct null not validError:Execution failed for task ':app:compileDebugAidl'.> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'E:\sdk\build-tools\23.0.0-preview\aidl.exe'' finished with non-zero exit value 3Information:BUILD FAILED**Information:Total time: 4.379 secsInformation:1 errorInformation:0 warningsInformation:See complete output in console
解决过程:查了很多网站,发现遇到的都是aidl is missing,好像没有遇到我这个问题的。他们的解决办法是右键选择app->open module setting-> 改变Build Tools Version 的版本。可能是因为编译器和sdk的版本不兼容的问题。参照[http://blog.csdn.net/songjinshi/article/details/46351851]
解决问题方案:
经过反复的新建项目,复制代码,改配置。突然发现一个问题。在Eclipse中自定义类可以不用添加包名,就可以编译成功。然后在Android Studio中就不行。
最后的解决办法就是在Person和Pet中添加包名就不会再有编译问题了。
值得说一句的是,在Android Studio中添加aidl文件,需要建立一个和java文件夹并列的aidl文件夹,然后包名也要一样。其实如果你通过右键点击创建aidl文件的时候,一般会自动创建这个目录结构。
接口IPet.aidl和Person.aidl,Pet.aidl自定义类放在一个目录中,Person和Pet的类文件,放在java文件夹下面。不得不说这样的分类结构还是很清晰明了的。本示例的代码是同一个应用程序中访问服务,然后返回某个人的宠物。大家也可以新建一个app,然后访问这个app的service。不多说了,上代码。
Pet.aidl
package com.x.myapplication;parcelable Pet;
Person.aidl
package com.x.myapplication;parcelable Person;
IPet.aidl
// IPet.aidlpackage com.x.myapplication;import com.x.myapplication.Person;import com.x.myapplication.Pet;interface IPet { List<Pet> getPets(in Person owner);}
Person.java
package com.x.myapplication;import android.os.Parcel;import android.os.Parcelable;/** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */public class Person implements Parcelable { private Integer id; private String name; private String pass; public Person() { } public Person(Integer id, String name, String pass) { super(); this.id = id; this.name = name; this.pass = pass; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPass() { return pass; } public void setPass(String pass) { this.pass = pass; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((pass == null) ? 0 : pass.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (pass == null) { if (other.pass != null) return false; } else if (!pass.equals(other.pass)) return false; return true; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { //把该对象所包含的数据写到Parcel dest.writeInt(id); dest.writeString(name); dest.writeString(pass); } // 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口 public static final Creator<Person> CREATOR = new Creator<Person>() { @Override public Person createFromParcel(Parcel source) { // 从Parcel中读取数据,返回Person对象 return new Person(source.readInt(), source.readString() , source.readString()); } @Override public Person[] newArray(int size) { return new Person[size]; } };}
Pet.java
import android.os.Parcel;import android.os.Parcelable;public class Pet implements Parcelable{ private String name; private double weight; public Pet() { } public Pet(String name, double weight) { super(); this.name = name; this.weight = weight; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } @Override public int describeContents() { return 0; } /* (non-Javadoc) * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int) */ @Override public void writeToParcel(Parcel dest, int flags) { //把该对象所包含的数据写到Parcel dest.writeString(name); dest.writeDouble(weight); } // 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口 public static final Creator<Pet> CREATOR = new Creator<Pet>() { @Override public Pet createFromParcel(Parcel source) { // 从Parcel中读取数据,返回Person对象 return new Pet(source.readString() , source.readDouble()); } @Override public Pet[] newArray(int size) { return new Pet[size]; } }; @Override public String toString() { return "Pet [name=" + name + ", weight=" + weight + "]"; }}
ComplexService.java
package com.x.myapplication;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class ComplexService extends Service { private PetBinder petBinder; private static Map<Person, List<Pet>> pets = new HashMap<Person, List<Pet>>(); static { // 初始化pets Map集合 ArrayList<Pet> list1 = new ArrayList<Pet>(); list1.add(new Pet("旺财", 4.3)); list1.add(new Pet("来福", 5.1)); pets.put(new Person(1, "sun", "sun"), list1); ArrayList<Pet> list2 = new ArrayList<Pet>(); list2.add(new Pet("kitty", 2.3)); list2.add(new Pet("garfield", 3.1)); pets.put(new Person(2, "bai", "bai"), list2); } // 继承Stub,也就是实现额IPet接口,并实现了IBinder接口 public class PetBinder extends IPet.Stub { @Override public List<Pet> getPets(Person owner) throws RemoteException { // 返回Service内部的数据 return pets.get(owner); } } @Override public void onCreate() { super.onCreate(); petBinder = new PetBinder(); } @Override public IBinder onBind(Intent arg0) { /* 返回catBinder对象 * 在绑定本地Service的情况下,该catBinder对象会直接 * 传给客户端的ServiceConnection对象 * 的onServiceConnected方法的第二个参数; * 在绑定远程Service的情况下,只将catBinder对象的代理 * 传给客户端的ServiceConnection对象 * 的onServiceConnected方法的第二个参数; */ return petBinder; } @Override public void onDestroy() { }}
MainActivity.java
import android.app.Service;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import java.util.List;public class MainActivity extends ActionBarActivity { private IPet petService; private Button get; EditText personView; ListView showView; private ServiceConnection conn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); personView = (EditText) findViewById(R.id.person); showView = (ListView) findViewById(R.id.show); get = (Button) findViewById(R.id.get); // 创建所需绑定服务的Intent Intent intent = new Intent(); intent.setAction("COMPLEX_SERVICE1"); conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 获取远程Service的onBind方法返回的对象的代理 Log.i("TAG", "Service is Connected"); petService = IPet.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { Log.i("TAG", "Service is Disconnected"); petService = null; } }; // 绑定远程服务 bindService(intent, conn, Service.BIND_AUTO_CREATE); get.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { try { String personName = personView.getText().toString(); Log.i("TAG", "personName is "+personName); // 调用远程Service的方法 Log.i("TAG", "petService is " + petService); List<Pet> pets = petService.getPets( new Person(1, personName , personName)); // 将程序返回的List包装成ArrayAdapter ArrayAdapter<Pet> adapter = new ArrayAdapter<Pet>( MainActivity.this , android.R.layout.simple_list_item_1 , pets); showView.setAdapter(adapter); } catch (RemoteException e) { e.printStackTrace(); } } }); } @Override public void onDestroy() { super.onDestroy(); // 解除绑定 this.unbindService(conn); }}
AndroidManifest.xml
<service android:name=".ComplexService">
<intent-filter >
<action android:name="COMPLEX_SERVICE1"/>
</intent-filter>
</service>
- Service中传递自定义类的问题分析
- Android service传递的问题
- Android Service:利用Binder通信中,传递自定义类型
- shell脚本中传输传递问题分析
- com中传递自定义类参数的解决方法
- 关于WebService传递自定义对象的问题
- Android中不同Activity之间传递自定义对象的参数问题的解决
- android中自定义service的详解(例子)
- 表单传递无法接收的问题分析
- angular--自定义服务--在多个控制器中传递参数factory+service+provider
- scrollerView与侧滑菜单滑动冲突的问题(自定义view结合事件传递机制实例分析)
- Spring中@Controller @Service的区别分析
- url中参数中传递"?"的问题
- Android中Service类onStartCommand的返回值问题
- Android中Service类onStartCommand的返回值问题
- Android中Service类onStartCommand的返回值问题
- Android中Service类onStartCommand的返回值问题
- Android中Service类onStartCommand的返回值问题
- Oracle循环语句
- hmm-前向算法
- row_number() over (partition by....order by...)用法
- 小型项目总结之四
- COJ 1204: Rectangles
- Service中传递自定义类的问题分析
- GRE写作必备句型
- Java关键字final、static使用总结
- linux文件基本操作(2)
- poj 2139 floyd()
- c++中的重载
- 小型项目总结之三
- UNITY3D学习笔记2
- Android中下载文件并保存到SD卡