Renderscript支持库存在问题

时间:2013-12-18 00:25:33

标签: java android eclipse renderscript android-sdk-tools

我正在尝试在API 16及更高版本的设备上使用Android Renderscript支持库,遵循步骤described here。到目前为止事情并不顺利。

我的Renderscript代码如下所示。

#pragma version(1)
#pragma rs java_package_name(com.xxx.renderscript.test)

#include "rs_time.rsh"

rs_script flipScript;
rs_allocation gIn;
rs_allocation gOut;
int width;
int height;
int direction = 0;

void root(uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) {
    if(direction == 0) { // flip horizontally
        const uchar4 *element = rsGetElementAt(gIn, width - x, y);
        float4 color = rsUnpackColor8888(*element);
        float4 output = {color.r, color.g, color.b};
        *v_out = rsPackColorTo8888(output);
    }
    else if(direction == 1) { // flip vertically
        const uchar4 *element = rsGetElementAt(gIn, x, height - y);
        float4 color = rsUnpackColor8888(*element);
        float4 output = {color.r, color.g, color.b};
        *v_out = rsPackColorTo8888(output);
    }
    else if(direction == 2) { // rotate left
        const uchar4 *element = rsGetElementAt(gIn, width - y, x);
        float4 color = rsUnpackColor8888(*element);
        float4 output = {color.r, color.g, color.b};
        *v_out = rsPackColorTo8888(output);
    }
    else if(direction == 3) { // rotate right
        const uchar4 *element = rsGetElementAt(gIn, y, height - x);
        float4 color = rsUnpackColor8888(*element);
        float4 output = {color.r, color.g, color.b};
        *v_out = rsPackColorTo8888(output);
    }
}

void flip(int testIdx) {
    int64_t  t0, t1;
    int64_t  t;
    t0 = rsUptimeNanos();
    rsForEach(flipScript, gIn, gOut);
    t1 = rsUptimeNanos();
    t = t1 - t0;
    rsDebug("  flip: timer on RS side: ", t);
}

首先我将Android SDK工具升级到22.3,将我的SDK平台工具升级到19.如果我单击ADT / Help / About ADT / Installation Details,我看到所有组件都已升级到22.3.0,开发人员除外工具,仍然是21.0.1:

  Android DDMS  22.3.0.v201310242005-887826 com.android.ide.eclipse.ddms.feature.group  The Android Open Source Project
  Android Developer Tools   21.0.1.201212060302 com.android.ide.eclipse.adt.package.product null
  Android Development Tools 22.3.0.v201310242005-887826 com.android.ide.eclipse.adt.feature.group   The Android Open Source Project
  Android Hierarchy Viewer  22.3.0.v201310242005-887826 com.android.ide.eclipse.hierarchyviewer.feature.group   The Android Open Source Project
  Android Native Development Tools  22.3.0.v201310242005-887826 com.android.ide.eclipse.ndk.feature.group   The Android Open Source Project
  Android Traceview 22.3.0.v201310242005-887826 com.android.ide.eclipse.traceview.feature.group The Android Open Source Project
  Tracer for OpenGL ES  22.3.0.v201310242005-887826 com.android.ide.eclipse.gldebugger.feature.group    The Android Open Source Project

然后我按照上述步骤中的建议编辑了我的“project.properties”文件。我也做了修改,加入了Tim Murray的评论。

proguard.config=C:/android/adt-bundle-windows-x86_64/sdk/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-18
renderscript.target=18
renderscript.support.mode=true
#sdk.buildtools=19.0.0

在我的Java代码中,我确保导入了支持库中的包。下面列出的是完整的Java文件:

package com.xxx.renderscript.test;

import android.support.v8.renderscript.*;
//import android.renderscript.RenderScript;
//import android.renderscript.Allocation;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

public class RenderScriptTestActivity extends Activity {

    private final String mLog = this.getClass().getName();
    private static final int TESTS_PER_GROUP = 12;

    private Bitmap mBitmapIn;
    private Bitmap mBitmapOut;
    private ImageView mDisplayView;

    private RenderScript mRS = null;
    private ScriptC_flip mScriptFlip = null;
    private Allocation mInPixelsAllocation = null;
    private Allocation mOutPixelsAllocation = null;

    //use aSyncTask so we display the image while rendering it.
    private ImageRenderTask mImageRenderTask = null;
    private boolean isRsBenchDone = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i(mLog, "onCreate() ");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_rs);

        mBitmapIn = loadBitmap(R.drawable.city);
        mBitmapOut = loadBitmap(R.drawable.city);

        mDisplayView = (ImageView) findViewById(R.id.rs_display);
        mDisplayView.setImageBitmap(mBitmapOut);

        // RS instances
        mRS = RenderScript.create(this);
        mScriptFlip = new ScriptC_flip(mRS, getResources(), R.raw.flip);

        mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
                                                          Allocation.MipmapControl.MIPMAP_NONE,
                                                          Allocation.USAGE_SCRIPT);
        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut,
                                                           Allocation.MipmapControl.MIPMAP_NONE,
                                                           Allocation.USAGE_SCRIPT);
    }

    @Override
    protected void onResume() {
        Log.i(mLog, "onResume ");
        super.onResume();

        // for thread & display control
        isRsBenchDone = true;
    }

    // initialize flip.rs
    private void setupRS() {
        Log.i(mLog, "Initializing flip.rs...");
        mScriptFlip.set_flipScript(mScriptFlip);
        mScriptFlip.set_width(mBitmapIn.getWidth());
        mScriptFlip.set_height(mBitmapIn.getHeight());
        mScriptFlip.set_gIn(mInPixelsAllocation);
        mScriptFlip.set_gOut(mOutPixelsAllocation);
    }

    @Override
    protected void onStop() {
        Log.i(mLog, "onStop ");
        super.onStop();
    }

    private void resetRS() {
        mBitmapIn  = null;
        mBitmapOut = null;
        mRS = null;
        mScriptFlip   = null;
        mInPixelsAllocation    = null;
        mOutPixelsAllocation   = null;
    }

    private Bitmap loadBitmap(int resource) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        Bitmap b_temp = BitmapFactory.decodeResource(getResources(), resource, options);
        int w = b_temp.getWidth();
        int h = b_temp.getHeight();
        Config cfg = b_temp.getConfig();
        Bitmap b_keep = Bitmap.createBitmap(w, h, cfg);
        Canvas c = new Canvas(b_keep);
        c.drawBitmap(b_temp, 0, 0, null);
        b_temp.recycle();

        if (true) {
            Log.d(mLog, "loadBitmap(): width = " + w + "  loadBitmap(): height = " + h);
        }
        return b_keep;
    }

    // press the button to invoke this function
    public void benchmark(View v) {
        if (false == isRsBenchDone) {  //do nothing if it's not done yet
            return;
        }
        if (mImageRenderTask != null) {
            if (mImageRenderTask.getStatus() == AsyncTask.Status.RUNNING) {
                return;
            }
            if (mImageRenderTask.getStatus() == AsyncTask.Status.PENDING) {
                mImageRenderTask.execute();
                return;
            }
        }
        // instantiate AsyncTask if not already existed & running
        Log.i(mLog, "User pressed Start");
        SystemClock.sleep(2000);
        isRsBenchDone = false;
        setupRS();
        mImageRenderTask = new ImageRenderTask();
        mImageRenderTask.execute();
    }

    // user presses this button when the test is done and all results have been
    // recorded.
    public void pressedRsExit(View view) {
        Log.i(mLog, "User pressed Exit");
        if (isRsBenchDone) {  // only exit when we are finished
            resetRS();
            RenderScriptTestActivity.this.finish();
        }
    }


    /**************************************************************************
     **
     *   Since the display must be updated in the main UI thread, and the main
     *   UI thread cannot be put to sleep, we have to use an AsyncTask to update
     *   the display after the image is rendered, and then sleep some time
     *   so that the tester can view the images being displayed.
     **
     **************************************************************************/
    private class ImageRenderTask extends AsyncTask<Void, Drawable, Void> {

        // runs in the UI (main) thread in correspondence to the AsyncTask
        // updating the drawable.
        protected void onProgressUpdate(Drawable... values) {
            Log.i(mLog, "onProgressUpdate...");
            super.onProgressUpdate(values);
            Drawable draw_tmp = values[0];
            mDisplayView.setImageDrawable(draw_tmp);
            mDisplayView.invalidate();
        }

        // runs on the UI (main) thread after the AsyncTask is finished
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            // reset the flag to exit
            isRsBenchDone = true;
        }

        @Override
        protected Void doInBackground(Void... params) {
            int group_id;
            int flip_way;

            //------------------------------------------------------------
            //                    group 4: flip horizontally
            //------------------------------------------------------------
            flip_way = 0;
            mScriptFlip.set_direction(flip_way);
            Log.i(mLog, "starting horizontal flipping ... ... ... ...");

            // measure group 4
            group_id = 4;  // used as a switch for render script
            measureRS(group_id);
            Log.i(mLog, "    horizontal done");

            // sleep cannot happen in the main UI thread
            SystemClock.sleep(2500);
            updateDisplay();
            SystemClock.sleep(2500);

            //------------------------------------------------------------
            //                    group 5: flip vertically
            //------------------------------------------------------------
            mScriptFlip.set_gIn(mInPixelsAllocation);
            flip_way = 1;
            mScriptFlip.set_direction(flip_way);
            Log.i(mLog, "starting vertical flipping ... ... ... ...");

            // measure group 5
            group_id = 5;  // used as a switch for render script
            measureRS(group_id);
            Log.i(mLog, "    vertical done");

            // sleep cannot happen in the main UI thread
            SystemClock.sleep(2500);
            updateDisplay();
            SystemClock.sleep(2500);

            return null;
        }

        // run and measure Render Script instances
        private void measureRS(int group_id) {
            if ((0==group_id) || (1 == group_id) || (2 == group_id)) {
                //other stuff
            }
            if (3 == group_id) {
                //other stuff
            }
            if ((4==group_id) || (5 == group_id)) {
                for (int i = 0; i < TESTS_PER_GROUP; i++) {
                    mScriptFlip.invoke_flip(i);
                }
            }
        }

        // update the displayed image
        private void updateDisplay() {
            Log.i(mLog, "updateDisplay...");
            //mOutPixelsAllocation.copyTo(mBitmapIn);  // this to verify the display.
            mOutPixelsAllocation.copyTo(mBitmapOut);
            Bitmap b_temp = Bitmap.createBitmap(mBitmapOut.getWidth(), mBitmapOut.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas c_temp = new Canvas(b_temp);
            c_temp.drawBitmap(mBitmapOut, 0, 0, null);
            Drawable d_temp = new BitmapDrawable(getResources(), b_temp);
            publishProgress(d_temp);
        }
    }
}

最后,在我的项目属性中,我将外部JAR添加到Java Build Path中:

renderscript-v8.jar - C:\android\adt-bundle-windows-x86_64\sdk\build-tools\19.0.0\renderscript\lib 

构建的代码没有任何问题。然后我在几台设备上测试了它。以下是测试结果。

Nexus 7(2012版,升级到Android 4.4) 代码运行完成而没有崩溃。但是,在第一次调用Renderscript之后,更新ImageView会导致显示空白。显然输出位图没有正确写入。

华为Mate(Android 4.1.2) 从ADT加载后代码崩溃。下面是一系列错误消息(帖子主体限制为30k字符,因此我无法发布所有内容):

W/dalvikvm(2246): Refusing to reopen boot DEX '/system/framework/hwframework.jar'
E/RenderScript_jni(2246): No GC methods
D/dalvikvm(2246): Trying to load lib /data/data/com.xxx.renderscript.test/lib/libRSSupport.so 0x41726918
D/dalvikvm(2246): Added shared lib /data/data/com.xxx.renderscript.test/lib/libRSSupport.so 0x41726918
D/dalvikvm(2246): No JNI_OnLoad found in /data/data/com.xxx.renderscript.test/lib/libRSSupport.so 0x41726918, skipping init
D/dalvikvm(2246): Trying to load lib /data/data/com.xxx.renderscript.test/lib/librsjni.so 0x41726918
D/dalvikvm(2246): Added shared lib /data/data/com.xxx.renderscript.test/lib/librsjni.so 0x41726918
V/RenderScript_jni(2246): RS compat mode
V/RenderScript(2246): 0x5bc7d008 Launching thread(s), CPUs 3
E/RenderScript(2246): Unable to open shared library (/data/data/com.xxx.renderscript.test//lib/librs.flip.so): Cannot load library: reloc_library[1306]:   132 cannot locate '_Z13rsUptimeNanosv'...
E/RenderScript(2246): Unable to open system shared library (/system/lib/librs.flip.so): (null)
D/AndroidRuntime(2246): Shutting down VM
W/dalvikvm(2246): threadid=1: thread exiting with uncaught exception (group=0x40f122a0)
E/AndroidRuntime(2246): FATAL EXCEPTION: main
E/AndroidRuntime(2246): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx.renderscript.test/com.xxx.renderscript.test.RenderScriptTestActivity}: android.support.v8.renderscript.RSRuntimeException: Loading of ScriptC script failed.

Sony Xperia Z Ultra C6802(Android 4.2.2) 从ADT加载后代码崩溃,并显示以下错误消息(再次选择以适应30k字符限制):

D/AndroidRuntime(3498): CheckJNI is OFF
D/dalvikvm(3498): Trying to load lib libjavacore.so 0x0
D/dalvikvm(3498): Added shared lib libjavacore.so 0x0
D/dalvikvm(3498): Trying to load lib libnativehelper.so 0x0
D/dalvikvm(3498): Added shared lib libnativehelper.so 0x0
I/ActivityManager(903): Start proc com.svox.pico for broadcast com.svox.pico/.VoiceDataInstallerReceiver: pid=3513 uid=10085 gids={50085, 1015, 1028}
I/ActivityManager(903): No longer want com.mobisystems.office:search (pid 2686): empty #34
I/ActivityManager(903): Start proc com.sonymobile.enterprise.service for broadcast com.sonymobile.enterprise.service/.Receiver: pid=3539 uid=1000 gids={41000, 3003, 1015, 1028, 3002, 3001, 3007}
D/AndroidRuntime(3498): Calling main entry com.android.commands.am.Am
D/dalvikvm(3498): Note: class Landroid/app/ActivityManagerNative; has 157 unimplemented (abstract) methods
I/ActivityManager(903): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.xxx.renderscript.test/.RenderScriptTestActivity} from pid 3498
D/AndroidRuntime(3498): Shutting down VM
D/jdwp(3498): Got wake-up signal, bailing out of select
D/dalvikvm(3498): Debugger has detached; object registry had 1 entries
D/dalvikvm(3557): Late-enabling CheckJNI
I/ActivityManager(903): Start proc com.xxx.renderscript.test for activity com.xxx.renderscript.test/.RenderScriptTestActivity: pid=3557 uid=10088 gids={50088, 1028}
D/dalvikvm(3557): Debugger has detached; object registry had 1 entries
I/Icing.InternalIcingCorporaProvider(2583): Updating corpora: A: com.xxx.renderscript.test, C: MAYBE
E/.AppDataSearchProvider(2583): Could not connect to AppDataSearchClient to register corpora.
W/Icing.InternalIcingCorporaProvider(2583): Corpora registration failed
I/com.xxx.renderscript.test.RenderScriptTestActivity(3557): onCreate() 
E/.AppDataSearchProvider(2583): Could not connect to AppDataSearchClient for notifyTableChanged
W/Icing.InternalIcingCorporaProvider(2583): Application table change notification failed.
D/dalvikvm(2856): GC_CONCURRENT freed 187K, 73% free 3028K/11084K, paused 3ms+4ms, total 20ms
D/ConnectionNotify(3116): queue add:2
D/AudioHardwareALSAExt(329): getParameters() supported_effect
D/[APP_SERVICE](3116): package com.xxx.renderscript.test installed
D/[APP_SERVICE](3116): add package com.xxx.renderscript.test
I/ActivityManager(903): Start proc com.UCMobile for broadcast com.UCMobile/.receivers.SysReceiver: pid=3587 uid=10207 gids={50207, 3003, 1015, 1028}
I/dalvikvm(3587): Turning on JNI app bug workarounds for target SDK version 8...
D/dalvikvm(3410): GC_CONCURRENT freed 511K, 71% free 3273K/11084K, paused 2ms+1ms, total 20ms
D/dalvikvm(3410): WAIT_FOR_CONCURRENT_GC blocked 5ms
E/RenderScript_jni(3557): No GC methods
D/dalvikvm(3557): Trying to load lib /data/app-lib/com.xxx.renderscript.test-1/libRSSupport.so 0x418243f8
D/dalvikvm(3557): Added shared lib /data/app-lib/com.xxx.renderscript.test-1/libRSSupport.so 0x418243f8
D/dalvikvm(3557): No JNI_OnLoad found in /data/app-lib/com.xxx.renderscript.test-1/libRSSupport.so 0x418243f8, skipping init
D/dalvikvm(3557): Trying to load lib /data/app-lib/com.xxx.renderscript.test-1/librsjni.so 0x418243f8
D/dalvikvm(3557): Added shared lib /data/app-lib/com.xxx.renderscript.test-1/librsjni.so 0x418243f8
V/RenderScript_jni(3557): RS compat mode
V/RenderScript(3557): 0x72b26978 Launching thread(s), CPUs 4
E/RenderScript(3557): Unable to open shared library (/data/data/com.xxx.renderscript.test//lib/librs.flip.so): Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "_Z13rsUptimeNanosv" referenced by "librs.flip.so"...
E/RenderScript(3557): Unable to open system shared library (/system/lib/librs.flip.so): (null)
D/AndroidRuntime(3557): Shutting down VM
W/dalvikvm(3557): threadid=1: thread exiting with uncaught exception (group=0x4154aae0)
E/AndroidRuntime(3557): FATAL EXCEPTION: main
E/AndroidRuntime(3557): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx.renderscript.test/com.xxx.renderscript.test.RenderScriptTestActivity}: android.support.v8.renderscript.RSRuntimeException: Loading of ScriptC script failed.
E/AndroidRuntime(3557):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2224)
E/AndroidRuntime(3557):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2274)
E/AndroidRuntime(3557):     at android.app.ActivityThread.access$600(ActivityThread.java:150)
E/AndroidRuntime(3557):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1276)
E/AndroidRuntime(3557):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(3557):     at android.os.Looper.loop(Looper.java:213)
E/AndroidRuntime(3557):     at android.app.ActivityThread.main(ActivityThread.java:5153)
E/AndroidRuntime(3557):     at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(3557):     at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(3557):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
E/AndroidRuntime(3557):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
E/AndroidRuntime(3557):     at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(3557): Caused by: android.support.v8.renderscript.RSRuntimeException: Loading of ScriptC script failed.
E/AndroidRuntime(3557):     at android.support.v8.renderscript.ScriptC.<init>(ScriptC.java:69)
E/AndroidRuntime(3557):     at com.xxx.renderscript.test.ScriptC_flip.<init>(ScriptC_flip.java:41)
E/AndroidRuntime(3557):     at com.xxx.renderscript.test.RenderScriptTestActivity.onCreate(RenderScriptTestActivity.java:53)
E/AndroidRuntime(3557):     at android.app.Activity.performCreate(Activity.java:5104)
E/AndroidRuntime(3557):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
E/AndroidRuntime(3557):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2188)
E/AndroidRuntime(3557):     ... 11 more
W/ActivityManager(903):   Force finishing activity com.xxx.renderscript.test/.RenderScriptTestActivity

如果有人可以查看问题,我是否会感激,无论是我的代码中的错误还是Android SDK问题。欢迎提出意见/建议,谢谢!

[编辑] 我从我的代码中删除了不相关的内容,并在此发布了完整的代码,希望有人可以重复我的问题,并找到解决方案。我还添加了更多的测试结果。

1 个答案:

答案 0 :(得分:2)

好。我不确定是否还需要它,以及它是否能解决您的问题,但我建议您尝试使用 Gradle 1.5.0的Android插件

必须在项目的build.gradle中设置(不在app build.gradle中)

//      imageData = NSData(contentsOfURL: imageUrl)

使用 buildToolsVersion 22.0.1或23.0.2 最新版本。