从错误的线程异常调用

nki*_*nki 5 java multithreading android

我正在尝试开发一个使用线程来实现幻灯片放映的应用程序.我正在从SQLite中检索图像路径并在ImageView上显示它们.问题,我被击中了,我感到困惑,所以我无法理解,我从哪个线程调用images()方法,我实际上是在实现幻灯片.

我得到了Logcat如下 -

    09-03 13:47:00.248: E/AndroidRuntime(10642): FATAL EXCEPTION: Thread-151
09-03 13:47:00.248: E/AndroidRuntime(10642): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
09-03 13:47:00.248: E/AndroidRuntime(10642):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5908)

09-03 13:47:00.248: E/AndroidRuntime(10642):    at com.example.fromstart.MainActivity.images(MainActivity.java:90)
09-03 13:47:00.248: E/AndroidRuntime(10642):    at com.example.fromstart.MainActivity$2.run(MainActivity.java:59)
09-03 13:47:00.248: E/AndroidRuntime(10642):    at java.lang.Thread.run(Thread.java:841)
Run Code Online (Sandbox Code Playgroud)

MainActivity.java:

public class MainActivity extends Activity
{
    ImageView jpgView;
    TextView tv;

    //adapter mDbAdapter;   
    adapter info = new adapter(this);
    String path; 
    Handler smHandler = new Handler() 
    {
        public void handleMessage(Message msg) 
        {
            TextView myTextView = 
            (TextView)findViewById(R.id.textView1);
            myTextView.setText("Button Pressed");
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        jpgView = (ImageView)findViewById(R.id.imageView1);
        tv = (TextView) findViewById(R.id.textView1);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    { 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);


        final Runnable runnable = new Runnable() 
        {
                 public void run() 
                 {
                            images();
                 }
        };
        int delay = 1000; // delay for 1 sec.
        int period = 15000; // repeat every 4 sec.
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() 
        {
            public void run() 
            {
                smHandler.post(runnable);
            }
        }, delay, period);
        Thread mythread = new Thread(runnable);
        mythread.start();
        return true;
}
        public void handleMessage(Message msg) 
        {             
            String string = "sample";
            TextView myTextView = (TextView)findViewById(R.id.textView1);
            myTextView.setText(string);
        }
        public void images()
        {
            try
            {
                 for(int i=0;i<=20;i++)
                {
                     path = info.getpath();
                Bitmap bitmap = BitmapFactory.decodeFile(path);
                jpgView.setImageBitmap(bitmap);

                }
            }
            catch(NullPointerException er)
            {
                String ht=er.toString();
                Toast.makeText(getApplicationContext(), ht, Toast.LENGTH_LONG).show();
            }
         }
    }
Run Code Online (Sandbox Code Playgroud)

我是android的新手,刚刚开始研究Threads.如果您在我的代码中发现任何错误,请指出这些错误并请建议我,正确的方法来处理这个问题.

提前致谢.

更新:

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final Handler mHandler = new Handler();

    // Create runnable for posting
    runOnUiThread(new Runnable() 
    {
        public void run() 
        {
            images();
        }
    });
    int delay = 1000; // delay for 1 sec.
    int period = 15000; // repeat every 4 sec.
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() 
    {
        public void run() 
        {
            images();
        }
    }, delay, period);




}

public void images()
{
    try
    {

    Toast.makeText(getApplicationContext(), "1", Toast.LENGTH_LONG).show();
             path = info.getpath(); 
             Toast.makeText(getApplicationContext(), "2", Toast.LENGTH_LONG).show();
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        Toast.makeText(getApplicationContext(), "3", Toast.LENGTH_LONG).show();
        jpgView.setImageBitmap(bitmap);
        Toast.makeText(getApplicationContext(), "4", Toast.LENGTH_LONG).show();

    }
    catch(NullPointerException er) 
   {
            String ht=er.toString();
            Toast.makeText(getApplicationContext(), ht, Toast.LENGTH_LONG).show();
    }
     }

}
Run Code Online (Sandbox Code Playgroud)

Rag*_*dan 8

您无法从线程更新/访问ui.

你有这个

     public void run() 
     {
           images();
     }
Run Code Online (Sandbox Code Playgroud)

在你有的图像

    jpgView.setImageBitmap(bitmap);
Run Code Online (Sandbox Code Playgroud)

你需要runOnUiThread用来更新ui.

    runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                      // do something
                    }
                });
Run Code Online (Sandbox Code Playgroud)

TimerTask也可以在不同的线程上运行.所以你使用了一个处理程序来进行更新.

您可以使用处理程序.

编辑:

Handler m_handler;
Runnable m_handlerTask ;  
m_handler = new Handler();   
m_handlerTask = new Runnable()
{
  @Override 
  public void run() { 

    // do something. call images() 
    m_handler.postDelayed(m_handlerTask, 1000);    

  }
  };
 m_handlerTask.run();
Run Code Online (Sandbox Code Playgroud)

如果您仍希望使用计时器任务 runOnUiThread

timer.scheduleAtFixedRate(new TimerTask() 
    {
        public void run() 
        {
              runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                      images();
                    }
                }); 

        }
    }, delay, period);
Run Code Online (Sandbox Code Playgroud)