Android java.lang.IllegalStateException:不应从主线程调用方法。使用毕加索时OnClick出错

Android java.lang.IllegalStateException:不应从主线程调用方法。使用毕加索时OnClick出错,android,onclick,picasso,unhandled-exception,Android,Onclick,Picasso,Unhandled Exception,我正在制作一个壁纸应用程序,我想将url中的图像设置为壁纸。 我使用 url = intent.getStringExtra("tmp"); 从以前的活动中。我在onClick方法中调用了这段代码 Bitmap result ; WallpaperManager wallpaperManager = WallpaperManager.getInstance(this); try { result= Picasso.with(this)

我正在制作一个壁纸应用程序,我想将url中的图像设置为壁纸。 我使用

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.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;
        }
    }


}
编辑: 我尝试了一个解决方案,但不起作用。它没有给出错误,但是当我点击按钮时,什么也没有发生。我的新代码:

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);
    }



}
包gc.x;
导入android.app.wallperManager;
导入android.content.Intent;
导入android.graphics.Bitmap;
导入android.graphics.drawable.drawable;
导入android.os.AsyncTask;
导入android.support.v7.app.AppActivity;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.Menu;
导入android.view.view;
导入android.widget.Button;
导入android.widget.ImageView;
导入android.widget.Toast;
导入com.squareup.picasso.picasso;
导入com.squareup.picasso.Target;
导入java.io.IOException;
公共类SecondActivity扩展AppCompatActivity实现View.OnClickListener{
图像加载器;
图像视图图像;
字符串url;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_秒);
Intent=this.getIntent();
//意图。getStringExtra(“tmp”);
image=(ImageView)findViewById(R.id.image4);
按钮按钮=(按钮)findViewById(R.id.button1);
imageLoader=新的imageLoader(this.getApplicationContext());
url=intent.getStringExtra(“tmp”);
显示图像(url,图像);
如果(按钮!=null)
setOnClickListener(SecondActivity.this);
}
@凌驾
公共void onClick(视图v){
新任务();
Toast.makeText(getApplicationContext(),“成功设置墙纸”,Toast.LENGTH\u SHORT.show();
}
公共类SetWallperTask扩展了AsyncTask{
@凌驾
受保护位图doInBackground(字符串…参数){
位图结果=空;
试一试{
结果=Picasso.with(getApplicationContext())
.加载(“https://www.geektopia.es/storage/geek/posts/2015/08/17/marshmallow.jpg")
.get();
}捕获(IOE异常){
e、 printStackTrace();
}
WallpaperManager=wallperManager.getInstance(getApplicationContext());
试一试{
壁纸管理器。挫折图(结果);
}捕获(IOEX异常){
例如printStackTrace();
}
返回结果;
}
@凌驾
受保护的void onPostExecute(位图结果){
super.onPostExecute(结果);
WallpareManager=wallpareManager.getInstance(getBaseContext());
试一试{
壁纸管理器。挫折图(结果);
}捕获(IOEX异常){
例如printStackTrace();
}
}
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
}
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
返回super.onCreateOptions菜单(菜单);
}
}

编辑:最初的问题是对异常的简单处理。一旦处理完毕,代码中就暴露出了更多的问题,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();
    }
}

这样做应该可以处理异常。

我定义了一个从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;
        }
    }


}

你确定吗?我认为这不是一个解决办法。是的,我试过了。当我放入IOException时,它首先给出结果位图的错误,因为它是在声明之前分配的。它修复了IOException吗?不清楚发生了什么对不起。位图结果是否在try catch中的“wallpermanager.setBitmap(result);”上方?我尝试了这个编辑过的解决方案,它解决了IOException问题,但出现了新的“java.lang.IllegalStateException:不应从主线程调用方法”。这可能会有所帮助。