当前位置:  编程技术>移动开发
本页文章导读:
    ▪[AndEngine学习课程] 第10节 box2D 物理碰撞系统        [AndEngine学习教程] 第10节 box2D 物理碰撞系统1.要点     顾着忙工作的事情,两周多没有写微博了,在上一节,基于AndEngine做了个碰撞检测的例子.这个例子对学习基本原理的作用还是有的, 但是用.........
    ▪ ListView跟性能        ListView和性能 一谈起ListView,我想大家都不陌生。而且最近该控件特别红,像QQ,人人和新浪客户端里都有它的影子。 其实实现ListView非常的简单。 我想大家都用过各种各样的控件,比如说一.........
    ▪ A more complicated thread sync issue about audioFlinger:EffectModule       A more complicated thread sync issue about audioFlinger::EffectModuleAudioFlinger中的一个线程同步引起的issue, 涉及到了audio方面更复杂点的Framework. [Symptom] 11-09 21:47:37.879   161  6305 W AudioFlinger: removeEffect_l() 0x41.........

[1][AndEngine学习课程] 第10节 box2D 物理碰撞系统
    来源: 互联网  发布时间: 2014-02-18
[AndEngine学习教程] 第10节 box2D 物理碰撞系统

1.要点

    顾着忙工作的事情,两周多没有写微博了,在上一节,基于AndEngine做了个碰撞检测的例子.这个例子对学习基本原理的作用还是有的,

但是用在游戏上就逊色点了,这节,主要基于Box2D系统来做碰撞检测.

   Box2D是一个用于模拟2D刚体物体的c++引擎,这里使用的是AndEngine的扩张插件,为了能够高效高速的使用它,底层的实现都是c++编写的,然后通过jni

调用实现的.所以虽然使用java编写代码,但是运行的也很流畅的.

 2.本节学习内容

     本节主要学习在AndEngine下引入Box2D插件.然后构建的基本物理实体碰撞.本例子主要实现4中外形的实体碰撞:

    矩形实体,圆形实体,三角形实体和正六边形实体;同过触摸屏幕可循环

动态地添加这几种实体.在一个模拟的重力环境下,根据g-sensor的数据来碰撞运动

3.工程配置准备

     在本例程的开始,已经讲解了如何配置AndEngine的开发环境.现在主要介绍如何使用Box2D扩张插件

    1.到官网下载Box2D插件,网址:https://github.com/nicolasgramlich/AndEnginePhysicsBox2DExtension

     2.解压后放到AndEngine同一个目录下,在eclipse下通过file->new->project->Android Project from Exist code,

       下一步找到box2d解压的文件夹

           

         点击finish.这是回到eclipse,回出现错误,因为没有包含AndEngine库进去,把鼠标放到box2d工程上,右键:

         build path->configurate build path.然后按照下图的方法,导入AndEngine的库

         

    接着把box2d工程下libs的andenginephysicsbox2dextension.jar拷贝到你的工程目录下的libs下面.这样字就完成了最基本可以使用的配置了


    如果想要在自己的工程中很好的使用eclipse中提供的自动完成功能,建议在自己的工程中进行如下设置:

   1.在工程中右键:build path->configurate build path.选中上边的libraries面板,然后点击add library,如下图所示:

   


接着next,点击user libraries->new->输入"Box2D"名称


Ok后点击add JARs..,一路点击OK finish就可以了.,最后到初始界面,把Box2D的顺序网上挪动到第二个,就是在AndEngine下面就可以了,这样方便编译.


4.代码编写

   1.折腾完基础的东西后,当然华丽丽的写代码啦,本例子主要用到5张图片,四个精灵和一张背景,内部成员变量如下设计

    

private static final int CAMERA_WIDTH = 800;
	private static final int CAMERA_HEIGHT = 480;
	
	private static final FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
	
	private TiledTextureRegion mBoxRegion;
	private TiledTextureRegion mCircleRegion;
	private TiledTextureRegion mTriangleRegion;
	private TiledTextureRegion mHexagonRegion;
	private SpriteBackground mBackground;
	
	private PhysicsWorld mPhysicsWorld;
	private int mSpriteCount = 0;
PhysicsWorld是这节内容的重点,是基于Box2D插件来的,具体的内容可以看源代码

2.接着初始化相应的资源

@Override
	public EngineOptions onCreateEngineOptions() {
		// TODO Auto-generated method stub
		SmoothCamera mCamera = new SmoothCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT, 10, 10, 5);
		EngineOptions mEngineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED,new RatioResolutionPolicy(CAMERA_WIDTH,CAMERA_HEIGHT),mCamera);
		return mEngineOptions;
	}
	
	@Override
	public void onCreateResources(
			OnCreateResourcesCallback pOnCreateResourcesCallback)
			throws Exception {
		// TODO Auto-generated method stub
		final BitmapTextureAtlas mTexture = new BitmapTextureAtlas(getTextureManager(), 1024, 1024, TextureOptions.BILINEAR_PREMULTIPLYALPHA);;
		final TiledTextureRegion mBackgroundRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "bg.png", 0, 0, 1, 1);
		mBackground = new SpriteBackground(new Sprite(0, 0,CAMERA_WIDTH ,CAMERA_HEIGHT , mBackgroundRegion, getVertexBufferObjectManager()));
		
		mBoxRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "face_box_tiled.png", 0, 640, 2, 1);
		mCircleRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "face_circle_tiled.png", 64, 640, 2, 1);
		mTriangleRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "face_triangle_tiled.png", 128, 640, 2, 1);
		mHexagonRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "face_hexagon_tiled.png", 192, 640, 2, 1);
		
		
	    mTexture.load();
	    
		pOnCreateResourcesCallback.onCreateResourcesFinished();
	}
3.创建场景,配置sensor和touch参数

                Scene mScene = new Scene();
		mScene.setBackground(mBackground);
		this.enableAccelerationSensor(this);
		mScene.setOnSceneTouchListener(this);

4.有了场景的框架后,我们就开始创建模式的物理世界了,这个世界是有范围的,

我们把它限制在的整个屏幕内:通过屏幕的四条边框进行限制;

this.mPhysicsWorld = new PhysicsWorld(new Vector2(0,SensorManager.GRAVITY_EARTH), false);
		final IAreaShape ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2, getVertexBufferObjectManager());
		final IAreaShape roof = new Rectangle(0, 0, CAMERA_WIDTH, 2,getVertexBufferObjectManager());
		final IAreaShape left = new Rectangle(0,0,2,CAMERA_HEIGHT,getVertexBufferObjectManager());
		final IAreaShape right = new Rectangle(CAMERA_WIDTH-2,0,2,CAMERA_HEIGHT,getVertexBufferObjectManager());

5.在模拟的物理世界中创建精灵实体
final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
		PhysicsFactory.createBoxBody(mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);
在这里的Fixture,是用来描述实体的:比如密度,弹性,和摩擦.这些内容我们在物理学中都有了解的

public static FixtureDef createFixtureDef(final float pDensity, final float pElasticity, final float pFriction) {
		return PhysicsFactory.createFixtureDef(pDensity, pElasticity, pFriction, false);
BodyType选择的是StaticBody,因为这里要求的限制框不能随着重力,碰撞等进行移动的,如果要移动的,像我们的精灵一样的,就要使用BodyType.DynamicBody类型

的啦

6.把各种角色加载到场景中去:

mScene.attachChild(ground);
		mScene.attachChild(roof);
		mScene.attachChild(left);
		mScene.attachChild(right);
		
		mScene.registerUpdateHandler(this.mPhysicsWorld);
		
		pOnCreateSceneCallback.onCreateSceneFinished(mScene);

5.画龙点睛

    1.使用手机上的g-sensor,让物理世界按照实际的倾斜来模拟

   

@Override
	public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onAccelerationChanged(AccelerationData pAccelerationData) {
		// TODO Auto-generated method stub
		this.mPhysicsWorld.setGravity(new Vector2(pAccelerationData.getX(),pAccelerationData.getY()));
	}

  2.实现点击屏幕,就在该处产生一个精灵:

@Override
	public boolean onSceneTouchEvent(Scene pScene, final TouchEvent pSceneTouchEvent) {
		// TODO Auto-generated method stub
		if(this.mPhysicsWorld != null){
			if(pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN){
				this.runOnUpdateThread(new Runnable(){

					@Override
					public void run() {
						// TODO Auto-generated method stub
						MyPhysics.this.addFace(pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
					}
					
					
					
				});
				
			}
			return true;
		}
		return false;
	}

 3.实现addFace函数

private void addFace( final float pX, final float pY){
		final Scene scene = this.mEngine.getScene();
		
		this.mSpriteCount++;
		
		final AnimatedSprite face;
		final Body body;
		
		if(this.mSpriteCount % 4 == 0){//矩形
			face = new AnimatedSprite(pX, pY, mBoxRegion, getVertexBufferObjectManager());
			body = PhysicsFactory.createBoxBody(mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
			
			face.animate(250);
			scene.attachChild(face);
			PhysicsConnector connector = new PhysicsConnector(face,body,true,true);
			this.mPhysicsWorld.registerPhysicsConnector(connector);
			
		}
		
		else if(this.mSpriteCount % 4 == 1){//圆形
			face =  new AnimatedSprite(pX,pY,mCircleRegion,getVertexBufferObjectManager() );
			body = PhysicsFactory.createCircleBody(mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
		
		    face.animate(250);
		    scene.attachChild(face);
		    PhysicsConnector connector = new PhysicsConnector(face,body,true,true);
		    this.mPhysicsWorld.registerPhysicsConnector(connector);
		}
		
		else if(this.mSpriteCount % 4 == 2){//三角形
			face =  new AnimatedSprite(pX,pY,mTriangleRegion,getVertexBufferObjectManager() );
			final float halfWidth = face.getWidthScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
			final float halfHeight = face.getHeightScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
			
			ArrayList<Vector2> vectors = new ArrayList<Vector2>();
			vectors.add(new  Vector2(0, - halfHeight));
			vectors.add(new Vector2(-halfWidth,halfHeight));
			vectors.add(new Vector2(halfWidth, halfHeight));
			body = PhysicsFactory.createTrianglulatedBody(mPhysicsWorld, face,vectors,BodyType.DynamicBody, FIXTURE_DEF);
		
		    face.animate(250);
		    scene.attachChild(face);
		    PhysicsConnector connector = new PhysicsConnector(face,body,true,true);
		    this.mPhysicsWorld.registerPhysicsConnector(connector);
		}
		
		else if(this.mSpriteCount % 4 == 3){//六边形
			face =  new AnimatedSprite(pX,pY,mHexagonRegion,getVertexBufferObjectManager() );
			final float halfWidth = face.getWidthScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
			final float halfHeight = face.getHeightScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
			
			/* The top and bottom vertex of the hexagon are on the bottom and top of hexagon-sprite. */
			final float top = -halfHeight;
			final float bottom = halfHeight;

			final float centerX = 0;

			/* The left and right vertices of the heaxgon are not on the edge of the hexagon-sprite, so we need to inset them a little. */
			final float left = -halfWidth + 2.5f / PIXEL_TO_METER_RATIO_DEFAULT;
			final float right = halfWidth - 2.5f / PIXEL_TO_METER_RATIO_DEFAULT;
			final float higher = top + 8.25f / PIXEL_TO_METER_RATIO_DEFAULT;
			final float lower = bottom - 8.25f / PIXEL_TO_METER_RATIO_DEFAULT;

			final Vector2[] vertices = {
					new Vector2(centerX, top),
					new Vector2(right, higher),
					new Vector2(right, lower),
					new Vector2(centerX, bottom),
					new Vector2(left, lower),
					new Vector2(left, higher)
			};

			
			body = PhysicsFactory.createPolygonBody(mPhysicsWorld, face,vertices,BodyType.DynamicBody, FIXTURE_DEF);
		
		    face.animate(250);
		    scene.attachChild(face);
		    PhysicsConnector connector = new PhysicsConnector(face,body,true,true);
		    this.mPhysicsWorld.registerPhysicsConnector(connector);
		}
		
	}
	

6.运行游戏,看结果

本例子的源代码:http://download.csdn.net/detail/cen616899547/4773538

















    
[2] ListView跟性能
    来源: 互联网  发布时间: 2014-02-18
ListView和性能


一谈起ListView,我想大家都不陌生。而且最近该控件特别红,像QQ,人人和新浪客户端里都有它的影子。

其实实现ListView非常的简单。

我想大家都用过各种各样的控件,比如说一个最简单的TextView,我们都是在布局文件里加入TextView标签,然后在Activity里通过findViewById(int id)方法得到该对象的引用,最后调用TextView类的setText(CharSequence s)方法设置该控件的值。

同样,对于ListView,我们先在布局文件里这样添加标签:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/mylist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

有了布局文件,然后我们在Activity里通过findViewById(int id)方法得到ListView对象的引用


ListView listView = (ListView) findViewById(R.id.mylist);

有了控件还不行,我们可以把ListView看作是一个可以伸缩的容器,我们需要往里添加内容。作为数据传输的桥梁,Adapter封装了所需的数据,通过调用ListView的方法setAdapter(Adapter a)将数据绑定到ListView中,这样屏幕上就有数据显示了。


Adapter是一个接口,定义了许多规范。Android提供了实现该接口的一些方便的类,如ArrayAdapter,CursorAdapter。下面以ArrayAdapter类为例讲解如何创建一个Adapter。


String[] values = new String[] { "Android", "iPhone", "WindowsMobile",
  "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X",
  "Linux", "OS/2" };

// First paramenter - Context
// Second parameter - Layout for the row
// Third parameter - ID of the TextView to which the data is written
// Forth - the Array of data
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
  android.R.layout.simple_list_item_1, android.R.id.text1, values);

是不是很简单?在上面的那个构造方法中,一共有四个参数,第一个参数很简单,就是一个上下文对象Context,第二个参数是描述每一行的布局,这里使用的是Android自带的一个简单布局,第三个参数是该View的id,最后一个是加入的数组。


上面的ArrayAdapter只能在每一行显示一些文本信息,如果想丰富一下,比如增加图片等,就需要继承该类,实现自己的自定义类。


public class MySimpleArrayAdapter extends ArrayAdapter<String> {
  private final Context context;
  private final String[] values;

  public MySimpleArrayAdapter(Context context, String[] values) {
    super(context, R.layout.rowlayout, values);
    this.context = context;
    this.values = values;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
    TextView textView = (TextView) rowView.findViewById(R.id.label);
    ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
    textView.setText(values[position]);
    String s = values[position];
    imageView.setImageResource(R.drawable.ok);
    return rowView;
  }
} 

继承该类最关键的就是复写getView()方法,因为ListView是通过该方法得到视图然后显示在屏幕上的。在本方法中,我们自定义了一个XML布局文件,里面有TextView标签和ImageView标签,分别用来显示文字和图片信息,这里是先得到系统服务LayoutInflater,调用该方法的inflate得到该布局的View,最后通过findViewById()方法获取TextView和ImageView的对象引用,再给它们赋值返回就结束了。



但是本章的讨论不是讲解如何实现ListView,但是考虑到有些没有接触过ListView的同志,就大概写了一点demo,同时以此例子为引子,指出该方法存在的一些性能问题。


由于通过调用LayoutInflater的inflate方法获得的View,其实会产生新的对象,创建对象是很耗时和资源的(内存),另外调用getViewById()方法也会相对耗时和耗资源,虽然其强度不如前者。

所以Android决定,如果代表每一行的View不可见(向下滑动,上面的View被遮住了,即为不可见),那么它将允许getView方法通过convertView复用该View,达到提升性能的目的。

我们先来看下ArrayAdapter是如何进行优化的。


 public View getView(int position, View convertView, ViewGroup parent) {
        return createViewFromResource(position, convertView, parent, mResource);
    }

    private View createViewFromResource(int position, View convertView, ViewGroup parent,
            int resource) {
        View view;
        TextView text;

        if (convertView == null) {
            view = mInflater.inflate(resource, parent, false);
        } else {
            view = convertView;
        }

        try {
            if (mFieldId == 0) {
                //  If no custom field is assigned, assume the whole resource is a TextView
                text = (TextView) view;
            } else {
                //  Otherwise, find the TextView field within the layout
                text = (TextView) view.findViewById(mFieldId);
            }
        } catch (ClassCastException e) {
            Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
            throw new IllegalStateException(
                    "ArrayAdapter requires the resource ID to be a TextView", e);
        }

        T item = getItem(position);
        if (item instanceof CharSequence) {
            text.setText((CharSequence)item);
        } else {
            text.setText(item.toString());
        }

        return view;
    }

该方法首先判断传给该方法的convertView是否为null,如果为null,那么就调用耗时的inflate方法创建View对象,如果不为空(该convertView是以前inflate过的,只不过被遮住了),就复用该对象,达到了部分优化。

上面之所以说是部分优化,是因为只考虑了优化inflate带来的负载,而忽略了getViewById()方法引起的性能问题。解决办法是在自定义Adapter类里引进静态内部类ViewHolder,如其名字,该类里存放我们需要显示每一行的所有控件,比如TextView,ImageView等。当convertView为空时,我们创建布局文件的View,然后分别得到布局里的各种控件,再把它们存放在ViewHolder类里,最后再调用convertView的 setTag(Object o)方法把该类绑定到该类里。


public class MyPerformanceArrayAdapter extends ArrayAdapter<String> {
  private final Activity context;
  private final String[] names;

  static class ViewHolder {
    public TextView text;
    public ImageView image;
  }

  public MyPerformanceArrayAdapter(Activity context, String[] names) {
    super(context, R.layout.rowlayout, names);
    this.context = context;
    this.names = names;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    if (rowView == null) {
      LayoutInflater inflater = context.getLayoutInflater();
      rowView = inflater.inflate(R.layout.rowlayout, null);
      ViewHolder viewHolder = new ViewHolder();
      viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
      viewHolder.image = (ImageView) rowView
          .findViewById(R.id.ImageView01);
      rowView.setTag(viewHolder);
    }

    ViewHolder holder = (ViewHolder) rowView.getTag();
    String s = names[position];
    holder.text.setText(s);
    if (s.startsWith("Windows7") || s.startsWith("iPhone")
        || s.startsWith("Solaris")) {
      holder.image.setImageResource(R.drawable.no);
    } else {
      holder.image.setImageResource(R.drawable.ok);
    }

    return rowView;
  }
} 

根据统计信息,这样的优化设计,比最初的方法效率上要快15%以上。


Over...


    
[3] A more complicated thread sync issue about audioFlinger:EffectModule
    来源: 互联网  发布时间: 2014-02-18
A more complicated thread sync issue about audioFlinger::EffectModule

AudioFlinger中的一个线程同步引起的issue, 涉及到了audio方面更复杂点的Framework.

[Symptom]

11-09 21:47:37.879   161  6305 W AudioFlinger: removeEffect_l() 0x41cc53f0 cannot promote chain for effect 0x42445ac8
11-09 21:47:37.879   161  6305 W AudioPolicyManagerBase: unregisterEffect() unknown effect ID 12251
11-09 21:47:37.879   161  6305 V VPT20   : EffectRelease 0x433fedf0
11-09 21:47:37.879   161  6305 V VPT20   : Vpt_release start
11-09 21:47:37.879   161  6305 V VPT20   : EmptyDataProc start
11-09 21:47:37.879   161  3294 V VPT20   : Vpt_cb_EventHandler OMX_EventBufferFlag
11-09 21:47:37.889   161  3294 E VPT20   : FillBuffer is no data
11-09 21:47:37.889   161  3294 V VPT20   : Vpt_cb_EventHandler OMX_EventBufferFlag
11-09 21:47:37.889   161  3294 E VPT20   : FillBuffer is no data
11-09 21:47:37.889   161  6305 V VPT20   : EmptyDataProc end
11-09 21:47:37.889   161  3294 V VPT20   : Vpt_cb_EventHandler OMX_CommandStateSet State:2
11-09 21:47:37.889   161  6305 V VPT20   : FreeBuffer start
11-09 21:47:37.889   161  6305 V VPT20   : FreeBuffer end
11-09 21:47:37.889   161  3294 V VPT20   : Vpt_cb_EventHandler OMX_CommandStateSet State:1
11-09 21:47:37.889   161  6305 V VPT20   : Vpt_release end
11-09 21:47:37.889   161  6305 V VPT20   : EffectRelease end
11-09 21:47:37.889   161  6305 F libc    : Fatal signal 11 (SIGSEGV) at 0x00000010 (code=1), thread 6305 (Binder_3)
11-09 21:47:37.999   156   156 I DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
11-09 21:47:37.999   156   156 I DEBUG   : Build fingerprint: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:userdebug/release-keys'
11-09 21:47:37.999   156   156 I DEBUG   : pid: 161, tid: 6305, name: Binder_3  >>> /system/bin/mediaserver <<<
11-09 21:47:37.999   156   156 I DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000010
11-09 21:47:38.619   610   611 D dalvikvm: GC_CONCURRENT freed 6991K, 44% free 11196K/19911K, paused 22ms+35ms, total 291ms
11-09 21:47:38.849   156   156 I DEBUG   :     r0 00000000  r1 00000010  r2 00000001  r3 00000001
11-09 21:47:38.849   156   156 I DEBUG   :     r4 4268cd30  r5 4268cd38  r6 42445ac8  r7 00000001
11-09 21:47:38.849   156   156 I DEBUG   :     r8 4268cdd4  r9 000000a1  sl 40319a6c  fp 00000001
11-09 21:47:38.849   156   156 I DEBUG   :     ip 00000003  sp 4268cd20  lr 4023dbbb  pc 40235228  cpsr 40000030
11-09 21:47:38.849   156   156 I DEBUG   :     d0  7361656c65527465  d1  7520292874636520
11-09 21:47:38.849   156   156 I DEBUG   :     d2  65206e776f6e6b65  d3  444920746365666e
11-09 21:47:38.849   156   156 I DEBUG   :     d4  ff431cfd2fddff23  d5  af7feaffff0de3ff
11-09 21:47:38.849   156   156 I DEBUG   :     d6  5100fa19e8fffcff  d7  000000005a251022
11-09 21:47:38.849   156   156 I DEBUG   :     d8  0000000000000000  d9  0000000000000000
11-09 21:47:38.849   156   156 I DEBUG   :     d10 0000000000000000  d11 0000000000000000
11-09 21:47:38.849   156   156 I DEBUG   :     d12 0000000000000000  d13 0000000000000000
11-09 21:47:38.849   156   156 I DEBUG   :     d14 0000000000000000  d15 0000000000000000
11-09 21:47:38.849   156   156 I DEBUG   :     d16 0000000000000000  d17 00000000000001f4
11-09 21:47:38.849   156   156 I DEBUG   :     d18 00000000000179a5  d19 9d32811804279cf3
11-09 21:47:38.849   156   156 I DEBUG   :     d20 bf3b893feeaf5f7d  d21 62f3fff0876afffe
11-09 21:47:38.849   156   156 I DEBUG   :     d22 250561599109be60  d23 1a36dab6b20e5dad
11-09 21:47:38.849   156   156 I DEBUG   :     d24 3fe999a1f2459fc7  d25 000000000000374c
11-09 21:47:38.849   156   156 I DEBUG   :     d26 00000000000001f2  d27 0000000000000000
11-09 21:47:38.849   156   156 I DEBUG   :     d28 00000000000174fe  d29 0000000000000213
11-09 21:47:38.849   156   156 I DEBUG   :     d30 0000000000003b66  d31 0000000000017316
11-09 21:47:38.849   156   156 I DEBUG   :     scr 60000010
11-09 21:47:38.859   156   156 I DEBUG   :
11-09 21:47:38.859   156   156 I DEBUG   : backtrace:
11-09 21:47:38.859   156   156 I DEBUG   :     #00  pc 00038228  /system/lib/libaudioflinger.so (android::wp<android::AudioFlinger::EffectHandle>::promote() const+7)
11-09 21:47:38.859   156   156 I DEBUG   :     #01  pc 00040bb7  /system/lib/libaudioflinger.so (android::AudioFlinger::EffectHandle::disconnect(bool)+76)
11-09 21:47:38.859   156   156 I DEBUG   :     #02  pc 00053531  /system/lib/libmedia.so (android::BnEffect::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+244)
11-09 21:47:38.859   156   156 I DEBUG   :     #03  pc 00014391  /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+60)
11-09 21:47:38.859   156   156 I DEBUG   :     #04  pc 00016f15  /system/lib/libbinder.so (android::IPCThreadState::executeCommand(int)+520)
11-09 21:47:38.859   156   156 I DEBUG   :     #05  pc 0001733d  /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+184)
11-09 21:47:38.869   156   156 I DEBUG   :     #06  pc 0001af55  /system/lib/libbinder.so
11-09 21:47:38.869   156   156 I DEBUG   :     #07  pc 00010e37  /system/lib/libutils.so (android::Thread::_threadLoop(void*)+114)
11-09 21:47:38.869   156   156 I DEBUG   :     #08  pc 0001099d  /system/lib/libutils.so
11-09 21:47:38.869   156   156 I DEBUG   :     #09  pc 00012df0  /system/lib/libc.so (__thread_entry+48)
11-09 21:47:38.869   156   156 I DEBUG   :     #10  pc 00012548  /system/lib/libc.so (pthread_create+172)
11-09 21:47:38.869   156   156 I DEBUG   :
11-09 21:47:38.869   156   156 I DEBUG   : stack:
11-09 21:47:38.869   156   156 I DEBUG   :          4268cce0  402de779  /system/lib/libc.so (dlfree)
11-09 21:47:38.869   156   156 I DEBUG   :          4268cce4  4268cd10  [stack:6305]
11-09 21:47:38.869   156   156 I DEBUG   :          4268cce8  42445ac8 
11-09 21:47:38.869   156   156 I DEBUG   :          4268ccec  00000001 
11-09 21:47:38.869   156   156 I DEBUG   :          4268ccf0  4268cd38  [stack:6305]
11-09 21:47:38.869   156   156 I DEBUG   :          4268ccf4  4268cdd4  [stack:6305]
11-09 21:47:38.869   156   156 I DEBUG   :          4268ccf8  4268cd10  [stack:6305]
11-09 21:47:38.869   156   156 I DEBUG   :          4268ccfc  402dff85  /system/lib/libc.so (free+12)
11-09 21:47:38.879   156   156 I DEBUG   :          4268cd00  4268cd10  [stack:6305]
11-09 21:47:38.879   156   156 I DEBUG   :          4268cd04  40233135  /system/lib/libaudioflinger.so (android::sp<android::AudioFlinger::Client>::~sp()+14)
11-09 21:47:38.879   156   156 I DEBUG   :          4268cd08  4268cd10  [stack:6305]
11-09 21:47:38.879   156   156 I DEBUG   :          4268cd0c  4023ad57  /system/lib/libaudioflinger.so (android::AudioFlinger::EffectModule::disconnect(android::wp<android::AudioFlinger::EffectHandle> const&, bool)+58)
11-09 21:47:38.879   156   156 I DEBUG   :          4268cd10  42445ac8 
11-09 21:47:38.879   156   156 I DEBUG   :          4268cd14  41cc53f0  [heap]
11-09 21:47:38.879   156   156 I DEBUG   :          4268cd18  df0027ad 
11-09 21:47:38.879   156   156 I DEBUG   :          4268cd1c  00000000 
11-09 21:47:38.879   156   156 I DEBUG   :     #00  4268cd20  00000001 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd24  41c73f70 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd28  4268cd38  [stack:6305]
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd2c  4023dbbb  /system/lib/libaudioflinger.so (android::AudioFlinger::EffectHandle::disconnect(bool)+80)
11-09 21:47:38.889   156   156 I DEBUG   :     #01  4268cd30  00000000 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd34  41f0a548 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd38  41c73f70 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd3c  41c73b38 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd40  00000000 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd44  41c73f70 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd48  4268ce04  [stack:6305]
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd4c  4268cdd4  [stack:6305]
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd50  00000004 
11-09 21:47:38.889   156   156 I DEBUG   :          4268cd54  400eb533  /system/lib/libmedia.so (android::BnEffect::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+246)
11-09 21:47:38.899   156   156 I DEBUG   :     #02  4268cd58  00000000 
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd5c  40430aa9  /system/lib/libbinder.so (android::Parcel::releaseObjects()+54)
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd60  4268cdd4  [stack:6305]
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd64  41cc2b20  [heap]
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd68  00000000 
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd6c  4268cdd4  [stack:6305]
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd70  00000034 
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd74  4268ce04  [stack:6305]
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd78  41c73f74 
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd7c  00000004 
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd80  4022e809  /system/lib/libaudioflinger.so (non-virtual thunk to android::AudioFlinger::EffectHandle::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int))
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd84  4268cdd4  [stack:6305]
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd88  000000a1 
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd8c  40319a6c 
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd90  00000001 
11-09 21:47:38.899   156   156 I DEBUG   :          4268cd94  4042b393  /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+62)
11-09 21:47:38.909   156   156 I DEBUG   :
11-09 21:47:38.909   156   156 I DEBUG   : memory near r4:
11-09 21:47:38.909   156   156 I DEBUG   :     4268cd10 42445ac8 41cc53f0 df0027ad 00000000  .ZDB.S.A.'......
11-09 21:47:38.909   156   156 I DEBUG   :     4268cd20 00000001 41c73f70 4268cd38 4023dbbb  ....p?.A8.hB..#@
11-09 21:47:38.909   156   156 I DEBUG   :     4268cd30 00000000 41f0a548 41c73f70 41c73b38  ....H..Ap?.A8;.A
11-09 21:47:38.909   156   156 I DEBUG   :     4268cd40 00000000 41c73f70 4268ce04 4268cdd4  ....p?.A..hB..hB
11-09 21:47:38.909   156   156 I DEBUG   :     4268cd50 00000004 400eb533 00000000 40430aa9 ....3..@......C@
11-09 21:47:38.909   156   156 I DEBUG   :
11-09 21:47:38.909   156   156 I DEBUG   : memory near r5:
11-09 21:47:38.919   156   156 I DEBUG   :     4268cd18 df0027ad 00000000 00000001 41c73f70  .'..........p?.A
11-09 21:47:38.919   156   156 I DEBUG   :     4268cd28 4268cd38 4023dbbb 00000000 41f0a548 8.hB..#@....H..A
11-09 21:47:38.919   156   156 I DEBUG   :     4268cd38 41c73f70 41c73b38 00000000 41c73f70  p?.A8;.A....p?.A
11-09 21:47:38.919   156   156 I DEBUG   :     4268cd48 4268ce04 4268cdd4 00000004 400eb533  ..hB..hB....3..@
11-09 21:47:38.919   156   156 I DEBUG   :     4268cd58 00000000 40430aa9 4268cdd4 41cc2b20 ......C@..hB +.A
11-09 21:47:38.919   156   156 I DEBUG   :
11-09 21:47:38.919   156   156 I DEBUG   : memory near r6:
11-09 21:47:38.919   156   156 I DEBUG   :     42445aa8 70696f76 616c665f 00003d67 00000013  voip_flag=......
11-09 21:47:38.919   156   156 I DEBUG   :     42445ab8 70696f76 616c665f 00003d67 00000169  voip_flag=..i...
11-09 21:47:38.919   156   156 I DEBUG   :     42445ac8 42445ac0 42445ac0 00000000 00000000  .ZDB.ZDB........
11-09 21:47:38.919   156   156 I DEBUG   :     42445ad8 42445e88 00000000 41f0a468 41c62fb8  .^DB....h..A./.A
11-09 21:47:38.919   156   156 I DEBUG   :     42445ae8 00002fdb 00002fd1 ec7178ec 4432e5e1  ./.../...xq...2D
11-09 21:47:38.919   156   156 I DEBUG   :
11-09 21:47:38.919   156   156 I DEBUG   : memory near r8:
11-09 21:47:38.919   156   156 I DEBUG   :     4268cdb4 4042df17 00000010 4042da21 41cd6f98 ..B@....!.B@.o.A
11-09 21:47:38.919   156   156 I DEBUG   :     4268cdc4 00000002 00000006 404aee57 41c73f74 ........W.J@t?.A
11-09 21:47:38.919   156   156 I DEBUG   :     4268cdd4 00000000 40c990c0 00000034 00000034 .......@4...4...
11-09 21:47:38.919   156   156 I DEBUG   :     4268cde4 00000034 40c990f4 00000000 00000000  4......@........
11-09 21:47:38.919   156   156 I DEBUG   :     4268cdf4 00000000 00010001 4042da21 41cd6f98 ........!.B@.o.A
11-09 21:47:38.919   156   156 I DEBUG   :
11-09 21:47:38.919   156   156 I DEBUG   : memory near sl:
11-09 21:47:38.919   156   156 I DEBUG   :     40319a4c 00000000 00000000 00000000 00000000  ................
11-09 21:47:38.919   156   156 I DEBUG   :     40319a5c 00000000 00000000 00000000 00000000  ................
11-09 21:47:38.919   156   156 I DEBUG   :     40319a6c 48e06d21 00000000 00000000 00000000  !m.H............
11-09 21:47:38.929   156   156 I DEBUG   :     40319a7c 00000000 00000000 00000000 00000000  ................
11-09 21:47:38.929   156   156 I DEBUG   :     40319a8c 00000000 00000000 00000000 00000000  ................
11-09 21:47:38.929   156   156 I DEBUG   :
11-09 21:47:38.929   156   156 I DEBUG   : memory near sp:
11-09 21:47:38.929   156   156 I DEBUG   :     4268cd00 4268cd10 40233135 4268cd10 4023ad57 ..hB51#@..hBW.#@
11-09 21:47:38.929   156   156 I DEBUG   :     4268cd10 42445ac8 41cc53f0 df0027ad 00000000  .ZDB.S.A.'......
11-09 21:47:38.929   156   156 I DEBUG   :     4268cd20 00000001 41c73f70 4268cd38 4023dbbb  ....p?.A8.hB..#@
11-09 21:47:38.929   156   156 I DEBUG   :     4268cd30 00000000 41f0a548 41c73f70 41c73b38  ....H..Ap?.A8;.A
11-09 21:47:38.929   156   156 I DEBUG   :     4268cd40 00000000 41c73f70 4268ce04 4268cdd4  ....p?.A..hB..hB
11-09 21:47:38.929   156   156 I DEBUG   :
11-09 21:47:38.929   156   156 I DEBUG   : code around pc:
11-09 21:47:38.929   156   156 I DEBUG   :     40235208 81f0e8bd 00011b8e 00011136 00011b5c  ........6...\...
11-09 21:47:38.929   156   156 I DEBUG   :     40235218 000110db 0001104d 4604b538 60202000  ....M...8..F.  `
11-09 21:47:38.929   156   156 I DEBUG   :     40235228 460d680b 6848b133 f7f34621 b108ebd8  .h.F3.Hh!F......
11-09 21:47:38.929   156   156 I DEBUG   :     40235238 60216829 bd384620 f100b573 46060410  )h!` F8.s......F
11-09 21:47:38.939   156   156 I DEBUG   :     40235248 f7fa4620 f106fc2b 46680108 ffe4f7ff   F..+.....hF....
11-09 21:47:38.939   156   156 I DEBUG   :
11-09 21:47:38.939   156   156 I DEBUG   : code around lr:
11-09 21:47:38.939   156   156 I DEBUG   :     4023db98 b11b9b02 46299803 ecfef7ea 202cf894  ......)F......,
11-09 21:47:38.939   156   156 I DEBUG   :     4023dba8 f894b19a b183302d 46686921 f7f73110  ....-0..!ihF.1..
11-09 21:47:38.939   156   156 I DEBUG   :     4023dbb8 9800fb33 6923b130 0110f104 6a5b2200  3...0.#i....."[j
11-09 21:47:38.939   156   156 I DEBUG   :     4023dbc8 ffb9f7ff f7f44668 6920ff56 f104b128  ....hF..V. i(...
11-09 21:47:38.939   156   156 I DEBUG   :     4023dbd8 f7ea0110 2000ecbe 69a16120 6a20b319  .......  a.i.. j
11-09 21:47:39.299  2882  2895 W AudioEffect: IEffect died
11-09 21:47:39.299   602 13457 W IMediaDeathNotifier: media server died
11-09 21:47:39.299   422   627 W IMediaDeathNotifier: media server died
11-09 21:47:39.299   422   681 W AudioEffect: IEffect died
11-09 21:47:39.309  1175  2873 W IMediaDeathNotifier: media server died
11-09 21:47:39.309   422   681 W AudioEffects-JNI: EVENT_ERROR
11-09 21:47:39.309  2882  2895 W AudioEffects-JNI: EVENT_ERROR
11-09 21:47:39.309   422   627 W MediaMetadataRetriever: MediaMetadataRetriever server died!
11-09 21:47:39.309  6929  7416 W MediaMetadataRetriever: MediaMetadataRetriever server died!
1
11-09 21:47:39.329  7895  7906 W MediaMetadataRetriever: MediaMetadataRetriever server died!

11-09 21:47:39.339   422   676 W AudioSystem: AudioFlinger server died!
11-09 21:47:39.339   422   676 E AudioEffectService: binderDied : AudioFlinger is dead.
11-09 21:47:39.339   422   710 W AudioSystem: AudioPolicyService server died!
11-09 21:47:39.339   602 31905 W AudioSystem: AudioFlinger server died!
11-09 21:47:39.339   602  8752 W AudioSystem: AudioPolicyService server died!
11-09 21:47:39.349  1175  3802 W AudioSystem: AudioFlinger server died!
11-09 21:47:39.629  2882  2894 W AudioSystem: AudioFlinger server died!

[Analysis]

The translated StackTrace:
#00  pc 00038228  /system/lib/libaudioflinger.so
android::wp<android::AudioFlinger::EffectHandle>::promote() const
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/native/include/utils/RefBase.h:433
#01  pc 00040bb7  /system/lib/libaudioflinger.so
android::AudioFlinger::EffectHandle::disconnect(bool)
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/av/services/audioflinger/AudioFlinger.cpp:9401
 #02  pc 00053531  /system/lib/libmedia.so
android::BnEffect::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/av/media/libmedia/IEffect.cpp:184
#03  pc 00014391  /system/lib/libbinder.so
android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/native/libs/binder/Binder.cpp:108
#04  pc 00016f15  /system/lib/libbinder.so
android::IPCThreadState::executeCommand(int)
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/native/libs/binder/IPCThreadState.cpp:1034
 #05  pc 0001733d  /system/lib/libbinder.so
android::IPCThreadState::joinThreadPool(bool)
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/native/libs/binder/IPCThreadState.cpp:473
#06  pc 0001af55  /system/lib/libbinder.so
android::PoolThread::threadLoop()
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/native/libs/binder/ProcessState.cpp:67
#07  pc 00010e37  /system/lib/libutils.so
android::Thread::_threadLoop(void*)
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/native/libs/utils/Threads.cpp:793
 #08  pc 0001099d  /system/lib/libutils.so
thread_data_t::trampoline(thread_data_t const*)
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/frameworks/native/libs/utils/Threads.cpp:132
#09  pc 00012df0  /system/lib/libc.so
__thread_entry
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/bionic/libc/bionic/pthread.c:217
 #10  pc 00012548  /system/lib/libc.so
pthread_create
/opt/Weekly_Release/Integration/5855/LINUX_JB_userdebug_single/bionic/libc/bionic/pthread.c:356

The releated source code lists as follows.

It can be found that the crash occurs in DISCONNECT handling of BBinder.
129status_t BnEffect::onTransact(
130    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
131{
132    switch (code) {
133        case ENABLE: {
134            ALOGV("ENABLE");
135            CHECK_INTERFACE(IEffect, data, reply);
136            reply->writeInt32(enable());
137            return NO_ERROR;
138        } break;
139
140        case DISABLE: {
141            ALOGV("DISABLE");
142            CHECK_INTERFACE(IEffect, data, reply);
143            reply->writeInt32(disable());
144            return NO_ERROR;
145        } break;
146
147        case COMMAND: {
148            ALOGV("COMMAND");
149            CHECK_INTERFACE(IEffect, data, reply);
150            uint32_t cmdCode = data.readInt32();
151            uint32_t cmdSize = data.readInt32();
152            char *cmd = NULL;
153            if (cmdSize) {
154                cmd = (char *)malloc(cmdSize);
155                data.read(cmd, cmdSize);
156            }
157            uint32_t replySize = data.readInt32();
158            uint32_t replySz = replySize;
159            char *resp = NULL;
160            if (replySize) {
161                resp = (char *)malloc(replySize);
162            }
163            status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp);
164            reply->writeInt32(status);
165            if (replySz < replySize) {
166                replySize = replySz;
167            }
168            reply->writeInt32(replySize);
169            if (replySize) {
170                reply->write(resp, replySize);
171            }
172            if (cmd) {
173                free(cmd);
174            }
175            if (resp) {
176                free(resp);
177            }
178            return NO_ERROR;
179        } break;
180
181        case DISCONNECT: {
182            ALOGV("DISCONNECT");
183            CHECK_INTERFACE(IEffect, data, reply);
184            disconnect();     ********************
185            return NO_ERROR;
186        } break;
187
188        case GET_CBLK: {
189            CHECK_INTERFACE(IEffect, data, reply);
190            reply->writeStrongBinder(getCblk()->asBinder());
191            return NO_ERROR;
192        } break;
193
194        default:
195            return BBinder::onTransact(code, data, reply, flags);
196    }
197}

In frameworks/av/services/audioflinger/AudioFlinger.cpp
9387void AudioFlinger::EffectHandle::disconnect()
9388{
9389    disconnect(true);
9390}
9391
9392void AudioFlinger::EffectHandle::disconnect(bool unpinIfLast)
9393{
9394    ALOGV("disconnect(%s)", unpinIfLast ? "true" : "false");
9395    if (mEffect == 0) {
9396        return;
9397    }
9398    mEffect->disconnect(this, unpinIfLast);
9399
9400    if (mHasControl && mEnabled) {
9401        sp<ThreadBase> thread = mEffect->thread().promote();  *******crash occurs in*****
9402        if (thread != 0) {
9403            thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
9404        }
9405    }
9406
9407    // release sp on module => module destructor can be called now
9408    mEffect.clear();
9409    if (mClient != 0) {
9410        if (mCblk != NULL) {
9411            // unlike ~TrackBase(), mCblk is never a local new, so don't delete
9412            mCblk->~effect_param_cblk_t();   // destroy our shared-structure.
9413        }
9414        mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
9415        // Client destructor must run with AudioFlinger mutex locked
9416        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
9417        mClient.clear();
9418    }
9419}


429template<typename T>
430sp<T> wp<T>::promote() const
431{
432    sp<T> result;
433    if (m_ptr && m_refs->attemptIncStrong(&result)) {    ****** crash occurs here ******
434        result.set_pointer(m_ptr);
435    }
436    return result;
437}

In wp<T>.promote(), we can know the SIGSEGV gives out at line #433, but we can't position precisely where the signal gives out. 

So, dump the assemble code.

Dump of assembler code for function android::wp<android::AudioFlinger::ThreadBase>::promote() const:
   0x00038220 <+0>: push {r3, r4, r5, lr}
   0x00038222 <+2>: mov r4, r0  r0 points to the returned sp<ThreadBase>, local result variable is optimized out.
   0x00038224 <+4>: movs r0, #0
   0x00038226 <+6>: str r0, [r4, #0] assign result.m_ptr with NULL;
   0x00038228 <+8>: ldr r3, [r1, #0] evaluate this.m_ptr, !!crash here!! 
   0x0003822a <+10>: mov r5, r1
   0x0003822c <+12>: cbz r3, 0x3823c <android::wp<android::AudioFlinger::ThreadBase>::promote() const+28>
   0x0003822e <+14>: ldr r0, [r1, #4]
   0x00038230 <+16>: mov r1, r4
   0x00038232 <+18>: blx 0x2b9e4
   0x00038236 <+22>: cbz r0, 0x3823c <android::wp<android::AudioFlinger::ThreadBase>::promote() const+28>
   0x00038238 <+24>: ldr r1, [r5, #0] 
   0x0003823a <+26>: str r1, [r4, #0] assign result.m_ptr with this.m_ptr
   0x0003823c <+28>: mov r0, r4
   0x0003823e <+30>: pop {r3, r4, r5, pc}
End of assembler dump.

From the code, the SIGSEGV crash occurs when the m_ptr of wp<ThreadBase> is to be evaluated in if block.
m_ptr is at the offset of 0x00 of wp<ThreadBase>, so, the 'this' pointer points to the wp<ThreadBase> object is wild pointer with value 0x10.

According to definitions of class EffectModule and class EffectHandle,
1545    class EffectModule: public RefBase {    @ AudioFlinger.h
1546    public:
 .......
1595        const wp<ThreadBase>& thread() { return mThread; }  ***************
 .......
1621        bool                mPinned;
 .......
1632mutable Mutex               mLock;      // mutex for process, commands and handles list protection
1633        wp<ThreadBase>      mThread;    // parent thread  ***************
1634        wp<EffectChain>     mChain;     // parent effect chain
 .......
1648    };

1656    class EffectHandle: public android::BnEffect {   @ AudioFlinger.h
 .........
1703    protected:
1704        friend class AudioFlinger;          // for mEffect, mHasControl, mEnabled
1705        EffectHandle(const EffectHandle&);
1706        EffectHandle& operator =(const EffectHandle&);
1707
1708        sp<EffectModule> mEffect;           // pointer to controlled EffectModule
1709        sp<IEffectClient> mEffectClient;    // callback interface for client notifications
1710        /*const*/ sp<Client> mClient;       // client for shared memory allocation, see disconnect()
1711        sp<IMemory>         mCblkMemory;    // shared memory for control block
1712        effect_param_cblk_t* mCblk;         // control block for deferred parameter setting via shared memory
1713        uint8_t*            mBuffer;        // pointer to parameter area in shared memory
1714        int mPriority;                      // client application priority to control the effect
1715        bool mHasControl;                   // true if this handle is controlling the effect
1716        bool mEnabled;                      // cached enable state: needed when the effect is
1717                                            // restored after being suspended
1718    };

The mEffect is sp<EffectModule> type.
EffectModule::thread() returns class EffectModule's mThread field which is at offset 0x10 of EffectModule.
So the mEffect.m_ptr is NULL, that is to say that object EffectHandle::mEffect has been cleared.

Notice some Effect object is released before the crash occurs.
-----------------------------------------------------------------------------

From the EffectModule object address and mId value printed in the log, part of the original EffectModule object may be re-drawn.
11-09 21:47:37.879   161  6305 W AudioFlinger: removeEffect_l() 0x41cc53f0--(ThreadBase*) cannot promote chain for effect 0x42445ac8(EffectModule*)
11-09 21:47:37.879   161  6305 W AudioPolicyManagerBase: unregisterEffect() unknown effect ID 12251 (0x2fdb)
11-09 21:47:37.879   161  6305 V VPT20   : EffectRelease 0x433fedf0 (effect_handle_t mEffectInterface of EffecModule)

11-09 21:47:38.919   156   156 I DEBUG   : memory near r6:
11-09 21:47:38.919   156   156 I DEBUG   :     42445aa8 70696f76 616c665f 00003d67 00000013  voip_flag=......
11-09 21:47:38.919   156   156 I DEBUG   :     42445ab8 70696f76 616c665f 00003d67 00000169  voip_flag=..i...
42445ac8 42445ac0 vtbl                    ?? may memory has been reused?
42445acc 42445ac0 RefBase::mRefs ?? may memory has been reused?
42445ad0 00000000 mPinned
42445ad4 00000000 mLock
42445ad8 42445e88 00000000 wp<ThreadBase>  {m_ptr, m_refs}
42445ae0 41f0a468 41c62fb8 wp<EffectChain> {m_ptr, m_refs}
42445ae8 00002fdb mId
42445aec 00002fd1 mSessionId
42445af0 ec7178ec 4432e5e1 mDescriptor {......}


8686void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle, bool unpinIfLast)
8687{
8688    ALOGV("disconnect() %p handle %p", this, handle.unsafe_get());
8689    // keep a strong reference on this EffectModule to avoid calling the
8690    // destructor before we exit
8691    sp<EffectModule> keep(this);
8692    {
8693        sp<ThreadBase> thread = mThread.promote();
8694        if (thread != 0) {
8695            thread->disconnectEffect(keep, handle, unpinIfLast);    ==calls==>>
8696        }
8697    }
8698}
8364void AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
8365                                                    const wp<EffectHandle>& handle,
8366                                                    bool unpinIfLast) {
8367
8368    Mutex::Autolock _l(mLock);
8369    ALOGV("disconnectEffect() %p effect %p", this, effect.get());
8370    // delete the effect module if removing last handle on it
8371    if (effect->removeHandle(handle) == 0) {
8372        if (!effect->isPinned() || unpinIfLast) {
8373            removeEffect_l(effect);     ===>>
8374            AudioSystem::unregisterEffect(effect->id());  ------ printed out
8375        }
8376    }
8377}

In AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle, bool unpinIfLast), AudioFlinger::ThreadBase::disconnectEffect is called.
AudioFlinger::ThreadBase::disconnectEffect in turn calls removeEffect_l and AudioSystem::unregisterEffect(..).
From the log,
AudioFlinger::ThreadBase::removeEffect_l claims that W AudioFlinger: removeEffect_l() 0x41cc53f0 cannot promote chain for effect 0x42445ac8,
AudioSystem::unregisterEffect(..) claims that AudioPolicyManagerBase: unregisterEffect() unknown effect ID 12251.
This gives us a light that the EffectModule maybe has been destroyed.

8641size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle)
8642{
8643    Mutex::Autolock _l(mLock);
8644    size_t size = mHandles.size();
8645    size_t i;
8646    for (i = 0; i < size; i++) {
8647        if (mHandles[i] == handle) break;
8648    }
8649    if (i == size) {
8650        return size;
8651    }
8652    ALOGV("removeHandle() %p removed handle %p in position %d", this, handle.unsafe_get(), i);
8653
8654    bool enabled = false;
8655    EffectHandle *hdl = handle.unsafe_get();
8656    if (hdl != NULL) {
8657        ALOGV("removeHandle() unsafe_get OK");
8658        enabled = hdl->enabled();
8659    }
8660    mHandles.removeAt(i);
8661    size = mHandles.size();
8662    // if removed from first place, move effect control from this handle to next in line
8663    if (i == 0 && size != 0) {
8664        sp<EffectHandle> h = mHandles[0].promote();
8665        if (h != 0) {
8666            h->setControl(true /*hasControl*/, true /*signal*/ , enabled /*enabled*/);
8667        }
8668    }
8669
8670    // Prevent calls to process() and other functions on effect interface from now on.
8671    // The effect engine will be released by the destructor when the last strong reference on
8672    // this object is released which can happen after next process is called.
8673    if (size == 0 && !mPinned) {
8674        mState = DESTROYED;
8675    }
8676
8677    return size;
8678}
For line #8664, is it safe for EffectHandle[0] if it is EffectModule's wrpper EffectHandle?? can this case be existed??
Though it maybe cause the EffectHandle destroyed, but EffectHandle::mEffect.m_ptr can't be NULL.
Except m_ptr is re-filled with zeros, it is most possible that mEffect.clear() is called.

8302void AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect) {
8303
8304    ALOGV("removeEffect_l() %p effect %p", this, effect.get());
8305    effect_descriptor_t desc = effect->desc();
8306    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
8307        detachAuxEffect_l(effect->id());
8308    }
8309
8310    sp<EffectChain> chain = effect->chain().promote();
8311    if (chain != 0) {
8312        // remove effect chain if removing last effect
8313        if (chain->removeEffect_l(effect) == 0) {
8314            removeEffectChain_l(chain);
8315        }
8316    } else {
8317        ALOGW("removeEffect_l() %p cannot promote chain for effect %p", this, effect.get());   ********claims*****
8318    }
8319}

949status_t AudioPolicyManagerBase::unregisterEffect(int id)
950{
951    ssize_t index = mEffects.indexOfKey(id);   ******** has been removed already **********
952    if (index < 0) {
953        LOGW("unregisterEffect() unknown effect ID %d", id); *****************claims******************
954        return INVALID_OPERATION;
955    }
956
957    EffectDescriptor *pDesc = mEffects.valueAt(index);
958
959    setEffectEnabled(pDesc, false);
960
961    if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) {
962        LOGW("unregisterEffect() memory %d too big for total %d",
963                pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
964        pDesc->mDesc.memoryUsage = mTotalEffectsMemory;
965    }
966    mTotalEffectsMemory -= pDesc->mDesc.memoryUsage;
967    LOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d",
968            pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
969
970    mEffects.removeItem(id);
971    delete pDesc;
972
973    return NO_ERROR;
974}
-------------------------------------------------------------------

From the log of above two functions print out, we can image that the EffectModule object is destroyed before those two functions called.
From the following log lines which is output by EffectRelease(), it is certain that the EffectModule is destroyed.
11-09 21:47:37.879   161  6305 V VPT20   : EffectRelease 0x433fedf0
11-09 21:47:37.879   161  6305 V VPT20   : Vpt_release start
11-09 21:47:37.879   161  6305 V VPT20   : EmptyDataProc start
11-09 21:47:37.879   161  3294 V VPT20   : Vpt_cb_EventHandler OMX_EventBufferFlag
11-09 21:47:37.889   161  3294 E VPT20   : FillBuffer is no data
11-09 21:47:37.889   161  3294 V VPT20   : Vpt_cb_EventHandler OMX_EventBufferFlag
11-09 21:47:37.889   161  3294 E VPT20   : FillBuffer is no data
11-09 21:47:37.889   161  6305 V VPT20   : EmptyDataProc end
11-09 21:47:37.889   161  3294 V VPT20   : Vpt_cb_EventHandler OMX_CommandStateSet State:2
11-09 21:47:37.889   161  6305 V VPT20   : FreeBuffer start
11-09 21:47:37.889   161  6305 V VPT20   : FreeBuffer end
11-09 21:47:37.889   161  3294 V VPT20   : Vpt_cb_EventHandler OMX_CommandStateSet State:1
11-09 21:47:37.889   161  6305 V VPT20   : Vpt_release end
11-09 21:47:37.889   161  6305 V VPT20   : EffectRelease end

8591AudioFlinger::EffectModule::~EffectModule()
8592{
8593    ALOGV("Destructor %p", this);
8594    if (mEffectInterface != NULL) {
8595        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
8596                (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
8597            sp<ThreadBase> thread = mThread.promote();
8598            if (thread != 0) {
8599                audio_stream_t *stream = thread->stream();
8600                if (stream != NULL) {
8601                    stream->remove_audio_effect(stream, mEffectInterface);
8602                }
8603            }
8604        }
8605        // release effect engine
8606        EffectRelease(mEffectInterface); ************
8607    }
8608}

It can be judged primarily as a race condition and thread sync issue.
EffectModule object is accessed via sp<EffectModule>, it should not destroyed abnormally.
So, the most case maybe EffectModule is destroyed explicitly via sp<T>.clear(), which decStrong reference and set sp<T>.m_ptr with NULL.

Find where mEffect.clear() is called besides AudioFlinger::EffectModule::~EffectModule() in AudioFlinger.cpp,

7699void AudioFlinger::purgeStaleEffects_l() {
7700
7701    ALOGV("purging stale effects");
7702

7721
7722    for (size_t i = 0; i < chains.size(); i++) {
7723        sp<EffectChain> ec = chains[i];
7724        int sessionid = ec->sessionId();
7725        sp<ThreadBase> t = ec->mThread.promote();
7726        if (t == 0) {
7727            continue;
7728        }

7740        if (!found) {
7741            // remove all effects from the chain
7742            while (ec->mEffects.size()) {
7743                sp<EffectModule> effect = ec->mEffects[0];
7744                effect->unPin();
7745                Mutex::Autolock _l (t->mLock);
7746                t->removeEffect_l(effect);
7747                for (size_t j = 0; j < effect->mHandles.size(); j++) {
7748                    sp<EffectHandle> handle = effect->mHandles[j].promote();
7749                    if (handle != 0) {
7750                        handle->mEffect.clear();       // *** Reference solution: should be Mutex::Autolock(..) here *******
7751                        if (handle->mHasControl && handle->mEnabled) {
7752                            t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
7753                        }
7754                    }
7755                }
7756                AudioSystem::unregisterEffect(effect->id());
7757            }
7758        }
7759    }
7760    return;
7761}

9944void AudioFlinger::EffectChain::setEffectSuspended_l(
9945        const effect_uuid_t *type, bool suspend)
9946{
9947    sp<SuspendedEffectDesc> desc;
9948    // use effect type UUID timelow as key as there is no real risk of identical
9949    // timeLow fields among effect type UUIDs.
9950    ssize_t index = mSuspendedEffects.indexOfKey(type->timeLow);
9951    if (suspend) {

9968    } else {
9969        if (index < 0) {
9970            return;
9971        }
9972        desc = mSuspendedEffects.valueAt(index);
9973        if (desc->mRefCount <= 0) {
9974            ALOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
9975            desc->mRefCount = 1;
9976        }
9977        if (--desc->mRefCount == 0) {
9978            ALOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
9979            if (desc->mEffect != 0) {
9980                sp<EffectModule> effect = desc->mEffect.promote();
9981                if (effect != 0) {
9982                    effect->setSuspended(false);
9983                    sp<EffectHandle> handle = effect->controlHandle();
9984                    if (handle != 0) {
9985                        effect->setEnabled(handle->enabled());
9986                    }
9987                }
9988                desc->mEffect.clear();
9989            }
9990            mSuspendedEffects.removeItemsAt(index);
9991        }
9992    }
9993}

10089void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
10090                                                            bool enabled)
10091{
10092    ssize_t index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
10093    if (enabled) {
10094        if (index < 0) {
10095            // if the effect is not suspend check if all effects are suspended

10112        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
10113        // if effect is requested to suspended but was not yet enabled, supend it now.
10114        if (desc->mEffect == 0) {
10115            desc->mEffect = effect;
10116            effect->setEnabled(false);
10117            effect->setSuspended(true);
10118        }
10119    } else {
10120        if (index < 0) {
10121            return;
10122        }
10123        ALOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
10124            effect->desc().type.timeLow);
10125        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
10126        desc->mEffect.clear();
10127        effect->setSuspended(false);
10128    }
10129}

So, the app should be well thread synced based on the thread model.
With the help from audio framework dept, find that purgeStaleEffects_l() called in releaseAudioSession is called in another thread that not well synchronized with the crash thread.

More, maybe it should be considered to prevent the whole EffectHandle's from being destroyed.
And notice the wp<T>'s life cycle, remember in mind that sp<T>'s destroy may cause T t's destroy.
Use wp<T>.promote() to try to get sp<T> everytime.


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3