无法在 aynctask 中未调用 Looper.prepare() 异常的线程内创建处理程序

Posted

技术标签:

【中文标题】无法在 aynctask 中未调用 Looper.prepare() 异常的线程内创建处理程序【英文标题】:Can't create handler inside thread that has not called Looper.prepare() Exception in aynctask 【发布时间】:2018-12-10 05:21:44 【问题描述】:

我收到以下代码的此错误。我该如何解决 ?为什么会这样?我是 android 和 java 的新手。请解释一下。

public class UpcomingMovies extends Activity 

    ArrayList<String> moviesList = new ArrayList<String>();
    ListView moviesListView ;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upcoming_movies);
        moviesListView= (ListView) findViewById(R.id.upcomingMoviesList);

        UpcomingMovies.this.runOnUiThread(new Runnable() 
            public void run() 
                new MovieInterface().execute() ;
            
        );
    

    public void setUpcomingMovieList(MovieResultsPage upcomingMovies) 
        for (MovieDb result : upcomingMovies.getResults()) 
            Log.d("api", result.getTitle().toString());
            moviesList.add(result.getTitle().toString());
        
        ArrayAdapter movieAdapter = new ArrayAdapter(getApplicationContext() , android.R.layout.simple_selectable_list_item , moviesList) ;
        moviesListView.setAdapter(movieAdapter);

    

    class MovieInterface extends AsyncTask<String , Void , MovieResultsPage>
    
        @Override
        protected MovieResultsPage doInBackground(String... strings) 

        TmdbMovies movies = new TmdbApi("d2e5d02fe295efc00bad8da4dc384edf").getMovies();
        MovieResultsPage upcomingMovies = movies.getUpcoming(null, 1, "IN");
        int totalpages = upcomingMovies.getTotalPages();
        Log.d("api" , "totalpages = " + Integer.toString(totalpages)) ;

        return upcomingMovies;
        

        @Override
        protected void onPostExecute(MovieResultsPage movieDbs) 
            super.onPostExecute(movieDbs);
            setUpcomingMovieList(movieDbs);
        
    

【问题讨论】:

【参考方案1】:

似乎问题是试图在不引用对象的情况下直接在new AsyncTaskCLass().execute() 上运行执行方法。

更换:

UpcomingMovies.this.runOnUiThread(new Runnable() 
            public void run() 
                new MovieInterface().execute() ;
            
        );

作者:

   MovieInterface movieInterface = new MovieInterface() ;
   movieInterface.execute() ;

修复它。

【讨论】:

【参考方案2】:

您只需要在 onPostExecute 中使用 runOnUiThread,在其他线程中启动一个线程有时会导致此错误,如果您必须以这种方式使用它,您必须释放 looper,但在这种情况下,我认为我的方式要容易得多:

public class UpcomingMovies extends Activity 

ArrayList<String> moviesList = new ArrayList<String>();
ListView moviesListView ;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_upcoming_movies);
    moviesListView= (ListView) findViewById(R.id.upcomingMoviesList);

    new MovieInterface().execute() ;


public void setUpcomingMovieList(MovieResultsPage upcomingMovies) 
    for (MovieDb result : upcomingMovies.getResults()) 
        Log.d("api", result.getTitle().toString());
        moviesList.add(result.getTitle().toString());
    
    ArrayAdapter movieAdapter = new ArrayAdapter(getApplicationContext() , android.R.layout.simple_selectable_list_item , moviesList) ;
    moviesListView.setAdapter(movieAdapter);



class MovieInterface extends AsyncTask<String , Void , MovieResultsPage>

    @Override
    protected MovieResultsPage doInBackground(String... strings) 

    TmdbMovies movies = new TmdbApi("d2e5d02fe295efc00bad8da4dc384edf").getMovies();
    MovieResultsPage upcomingMovies = movies.getUpcoming(null, 1, "IN");
    int totalpages = upcomingMovies.getTotalPages();
    Log.d("api" , "totalpages = " + Integer.toString(totalpages)) ;

    return upcomingMovies;
    

    @Override
    protected void onPostExecute(MovieResultsPage movieDbs) 
        super.onPostExecute(movieDbs);
        UpcomingMovies.this.runOnUiThread(new Runnable() 
            public void run() 
              setUpcomingMovieList(movieDbs);
            
        );
    


【讨论】:

以上是关于无法在 aynctask 中未调用 Looper.prepare() 异常的线程内创建处理程序的主要内容,如果未能解决你的问题,请参考以下文章

无法在未调用 Looper 准备的线程内创建处理程序 [重复]

无法在未调用 Looper 的线程内创建处理程序 [重复]

无法在未调用 Looper.prepare()3 的线程内创建处理程序

无法在未调用 Looper.prepare() 的线程内创建处理程序

无法在未调用 Looper.prepare() 的线程内创建处理程序

原因:无法在未调用 Looper.prepare() 的线程上敬酒