java.lang.IllegalStateException:方法调用不应该从主线程发生。使用Picasso时OnClick出错

时间:2016-10-18 21:23:17

标签: android onclick picasso unhandled-exception

我正在制作壁纸应用,我想将网址中的图像设置为壁纸。 我使用

指定了网址
url = intent.getStringExtra("tmp");

来自之前的活动。我在 onClick 方法中调用了此代码。

  Bitmap result ;
  WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
  try {
            result= Picasso.with(this)
                    .load(url)
                    .get();
            wallpaperManager.setBitmap(result);
        } catch (IOException ex) {
            ex.printStackTrace();
        }

我正在使用毕加索库将图像设置为壁纸,但我遇到了一个问题,我无法理解为什么会出现此错误。

不是: ImageLoader是另一个显示图片的类。

的活动:

package gc.x;

import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.squareup.picasso.Picasso;

import java.io.IOException;

public class SecondActivity extends AppCompatActivity implements View.OnClickListener {

    ImageLoader imageLoader;
    ImageView image;
    String url;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Intent intent = this.getIntent();
      //  intent.getStringExtra("tmp");

        image = (ImageView)findViewById(R.id.image4) ;

        Button button = (Button) findViewById(R.id.button1);


        imageLoader = new ImageLoader(this.getApplicationContext());

        url = intent.getStringExtra("tmp");
        imageLoader.DisplayImage(url, image);


        if(button != null)
        button.setOnClickListener(SecondActivity.this);






    }


    @Override
    public void onClick(View v) {

        Bitmap result ;
        WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
        try {
            result= Picasso.with(this)
                    .load(url)
                    .get();
            wallpaperManager.setBitmap(result);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }



}

编辑: 我试过一个解决方案,但它没有用。它没有给出错误,但是当我点击按钮时没有任何反应。我的新代码:

package gc.x;

import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;

import java.io.IOException;

public class SecondActivity extends AppCompatActivity implements View.OnClickListener {

    ImageLoader imageLoader;
    ImageView image;
    String url;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Intent intent = this.getIntent();
      //  intent.getStringExtra("tmp");

        image = (ImageView)findViewById(R.id.image4) ;

        Button button = (Button) findViewById(R.id.button1);


        imageLoader = new ImageLoader(this.getApplicationContext());

        url = intent.getStringExtra("tmp");
        imageLoader.DisplayImage(url, image);


        if(button != null)
        button.setOnClickListener(SecondActivity.this);

    }


    @Override
    public void onClick(View v) {
        new SetWallpaperTask();
        Toast.makeText(getApplicationContext(), "Set wallpaper successfully", Toast.LENGTH_SHORT).show();

    }

    public class SetWallpaperTask extends AsyncTask<String, Void, Bitmap> {

        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap result= null;
            try {
                result = Picasso.with(getApplicationContext())
                        .load("https://www.geektopia.es/storage/geek/posts/2015/08/17/marshmallow.jpg")
                        .get();
            } catch (IOException e) {
                e.printStackTrace();
            }

            WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
            try {
                wallpaperManager.setBitmap(result);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute (Bitmap result) {
            super.onPostExecute(result);

            WallpaperManager wallpaperManager = WallpaperManager.getInstance(getBaseContext());
            try {
                wallpaperManager.setBitmap(result);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        protected void onPreExecute () {
            super.onPreExecute();

        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return super.onCreateOptionsMenu(menu);
    }



}

2 个答案:

答案 0 :(得分:1)

我定义了一个从url

返回位图的方法
   public static Bitmap getBitmapFromURL(String src) {
        try {
            URL url = new URL(src);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            // Log exception
            return null;
        }
    }

然后在OnClick方法中新建一个线程,以防止android.os.NetworkOnMainThreadException错误。

Thread thread = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try  {
                            WallpaperManager myWallpaperManager
                                    = WallpaperManager.getInstance(getApplicationContext());
                            Bitmap bitmap= getBitmapFromURL(url);
                            if(bitmap!=null)
                                myWallpaperManager.setBitmap(bitmap);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });

                thread.start();

最终活动:

package gc.x;

import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class SecondActivity extends Activity {

    ImageLoader imageLoader;
    ImageView image;
    String url;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Intent intent = this.getIntent();
      //  intent.getStringExtra("tmp");

        image = (ImageView)findViewById(R.id.image4) ;

        Button button = (Button) findViewById(R.id.button1);


        imageLoader = new ImageLoader(this.getApplicationContext());

        url = intent.getStringExtra("tmp");
        imageLoader.DisplayImage(url, image);

        if(button != null)
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                Thread thread = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try  {
                            WallpaperManager myWallpaperManager
                                    = WallpaperManager.getInstance(getApplicationContext());
                            Bitmap bitmap= getBitmapFromURL(url);
                            if(bitmap!=null)
                                myWallpaperManager.setBitmap(bitmap);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });

                thread.start();

            }
        });

    }

    public static Bitmap getBitmapFromURL(String src) {
        try {
            URL url = new URL(src);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            // Log exception
            return null;
        }
    }


}

答案 1 :(得分:0)

编辑:原始问题是对异常的简单处理。一旦处理,它揭示了代码中的其他问题,OP已经改变了他的问题以反映。没有提到他原来的问题。

放置

        Bitmap result= Picasso.with(this) //XX Problem Occurs Here
            .load("url") 
            .get();

在IOException中,try / catch应该解决这个问题。

想象一下,没有什么可以加载()。get()你会有一个IOException。由于存在这种可能性,因此您需要在发生这种情况时对其进行处理。

    @Override
public void onClick(View v) {

    Bitmap result;
    WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);

    try {
        result = Picasso.with(this).load("url").get();
        wallpaperManager.setBitmap(result);

    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

这样做应该处理异常。