0

我遇到了异常问题NetworkOnMainThreadException

所以我必须为 asynctask 提供一个函数,问题是我必须发送两个参数,这两个参数与发送和接收它们不同。

这些是需要发送的参数,所以 asynctask 接收它们

TypedArray array
Boolean true

public void SetImages(TypedArray array){
   SetImages(array, true); // OLD CALL
   new task().execute   // NEW CALL
} 

这是我需要带到 asynctask 的代码

public void SetImages(TypedArray array, boolean reflected){

    final int reflectionGap = 4;

//          Drawable[] drawables = new Drawable[array.length()];
//          mImages = new CarouselImageView[array.length()];
    mImages = new CarouselImageView[MainActivity.aL_home.size()];
    Log.e("TAG", "SIZE OF: "+MainActivity.aL_home.size());
    for(int i = 0; i< MainActivity.aL_home.size(); i++)
    {
        try {
            Log.e("TAG","url: "+MainActivity.aL_home.get(i).getUrl_imagen());
//              drawables[i] = array.getDrawable(i);
//              Bitmap originalImage = ((BitmapDrawable)drawables[i]).getBitmap();
            Bitmap originalImage = BitmapFactory.decodeStream((InputStream)new URL(MainActivity.aL_home.get(i).getUrl_imagen()).getContent());
            if(reflected){
                int width = originalImage.getWidth();
                int height = originalImage.getHeight();

                // This will not scale but will flip on the Y axis
                Matrix matrix = new Matrix();
                matrix.preScale(1, -1);

                // Create a Bitmap with the flip matrix applied to it.
                // We only want the bottom half of the image
                Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
                        height / 2, width, height / 2, matrix, false);

                // Create a new bitmap with same width but taller to fit
                // reflection
                Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
                        (height + height / 2), Config.ARGB_8888);

                // Create a new Canvas with the bitmap that's big enough for
                // the image plus gap plus reflection
                Canvas canvas = new Canvas(bitmapWithReflection);
                // Draw in the original image
                canvas.drawBitmap(originalImage, 0, 0, null);
                // Draw in the gap
                Paint deafaultPaint = new Paint();
                canvas.drawRect(0, height, width, height + reflectionGap,
                        deafaultPaint);
                // Draw in the reflection
                canvas.drawBitmap(reflectionImage, 0, height + reflectionGap,
                        null);

                // Create a shader that is a linear gradient that covers the
                // reflection
                Paint paint = new Paint();
                LinearGradient shader = new LinearGradient(0,
                        originalImage.getHeight(), 0,
                        bitmapWithReflection.getHeight() + reflectionGap,
                        0x70ffffff, 0x00ffffff, TileMode.CLAMP);
                // Set the paint to use this shader (linear gradient)
                paint.setShader(shader);
                // Set the Transfer mode to be porter duff and destination in
                paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
                // Draw a rectangle using the paint with our linear gradient
                canvas.drawRect(0, height, width,
                        bitmapWithReflection.getHeight() + reflectionGap, paint);

                originalImage = bitmapWithReflection;
            }

            CarouselImageView imageView = new CarouselImageView(mContext);
            imageView.setImageBitmap(originalImage);
            imageView.setIndex(i);

            ////////imageView.setLayoutParams(new CarouselOld.LayoutParams(120, 180));
            ////////imageView.setScaleType(ScaleType.MATRIX);
            mImages[i] = imageView;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
4

4 回答 4

1

NetworkOnMainThreadException

如果您尝试从与 Main(UI) 线程不同步的后台线程操作和更改 UI,则会引发这种异常。

AsyncTask 提供了一些可以更新 UI 的方法:

  • 预执行
  • onProgressUpdate
  • 后执行

并且您应该只在提到的方法中执行任何 UI 更新。

这是我需要带到 asynctask 的代码

因此,将您的方法移动到 AsyncTask 类并通过 AsyncTask 的构造函数传递所需的参数(TypedArray 和 Boolean),即

Task task = new Task(arr, boolVariable);
task.execute();
于 2013-04-09T08:54:54.637 回答
0

我认为,您仍然在主线程上调用网络代码。很可能,忘记评论一些东西。

请参阅 如何修复 android.os.NetworkOnMainThreadException?

于 2013-04-09T08:53:18.280 回答
0

所以问题是如何将参数传递给AsyncTask?

格式是

private class MyTask extends AsyncTask<Params, Progress, Result> { ... }

http://developer.android.com/reference/android/os/AsyncTask.html

所以你可以定义你的 AsyncTask 像

private class SetImagesTask extends AsyncTask<TypedArray, Void, Void> { 
    protected Void doInBackground(TypedArray... typedArrays) {
        TypedArray array = typedArrays[0];
        ...
    }
    ...
}

并称它为

new SetImagesTask.execute(array);

对于布尔值,您可以使用主类字段或静态变量,因此您可以在执行(数组)之前设置它。或者,您可以将布尔值包装到第二个 TypedArray 中,并传递它们的数组,如 execute(new TypedArray[] {array, booleanArray});

于 2013-04-09T08:55:59.947 回答
0

NetworkOnMainThread 发生异常是因为您正在主 UI 线程上运行与网络相关的操作。这仅针对针对 Honeycomb SDK 或更高版本的应用程序抛出

http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

您应该使用异步任务。

http://developer.android.com/reference/android/os/AsyncTask.html

在 onCreate()

new TheTask().execute();

您还可以将 url 等参数传递给 AsyncTask 的构造函数,并在 doInBackground() 中使用相同的参数

class TheTask extends AsyncTask<Void,Void,Void>
{
 protected void onPreExecute()
{           super.onPreExecute();
        //display progressdialog.
} 

protected void doInBackground(Void ...params)//return result here
{  
    //http request. do not update ui here

    return null;
} 

protected void onPostExecute(Void result)//result of doInBackground is passed a parameter
{     
        super.onPostExecute(result);
        //dismiss progressdialog.
        //update ui using the result returned form doInbackground()
 } 
 }

当一个异步任务被执行时,任务会经过 4 个步骤:

  1. onPreExecute(),在任务执行之前在 UI 线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

  2. doInBackground(Params...),在 onPreExecute() 完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数传递到这一步。计算的结果必须由这一步返回,并将传递回最后一步。此步骤还可以使用 publishProgress(Progress...) 来发布一个或多个进度单位。这些值在 UI 线程上的 onProgressUpdate(Progress...) 步骤中发布。

  3. onProgressUpdate(Progress...),在调用 publishProgress(Progress...) 后在 UI 线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时在用户界面中显示任何形式的进度。例如,它可用于动画进度条或在文本字段中显示日志。

  4. onPostExecute(Result),在后台计算完成后在 UI 线程上调用。后台计算的结果作为参数传递给该步骤。

于 2013-04-09T08:56:13.907 回答