Android 片段未从界面更新图像

Android Fragment Not Updating Image From Interface

我正在尝试通过接口将图像从另一个线程更新为片段。代码确实设法进入界面,但每次进入 Left_Image.setImageDrawable(Image_Rotated); 时,我都会收到空指针异常。如果在为片段创建时我设置了一个图像,它可以工作,但是一旦它尝试为接口执行它,它就会出现空指针异常。我使用命令 isAdded()) 来检查片段是否已附加,并且它总是毫无结果地返回,但我似乎无法修复它并附加它。这是代码

片段:

import android.app.Activity;
import android.app.FragmentManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import java.util.logging.Handler;

public class Augmented_Reality extends PreferenceFragment implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mRotationVectorSensor;
private Sensor mMagneticSensor;
private final float[] mRotationMatrix = new float[16];
private Boolean MagnetButtonPressed = false;
private Boolean Left;
private Boolean Right;

Boolean Admin_Mode;

boolean Lock = false;

public SharedPreferences sharedpreferences;
public static final String MyPREFERENCES = "MyPrefs";


ToggleButton HeadTracker;
TextView Position;
TextView Position_Left;
TextView Position_Right;

ImageView Left_Image;
ImageView Right_Image;

private Image_Packet_Flag Image_Flag;
public final byte Image_Sync_Flag = 0x09;

private Context context;

Activity activity;



public Augmented_Reality() {

    Image_Flag = new Image_Packet_Flag();

}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    context = activity;



}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
        mSensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);

        mRotationVectorSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
        mMagneticSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);


        mSensorManager.registerListener(this, mRotationVectorSensor, 10000);
        mSensorManager.registerListener(this, mMagneticSensor, 10000);
    } catch (Exception ex) {
        Toast.makeText(getActivity().getApplicationContext(), "failed sensor", Toast.LENGTH_SHORT).show();
    }
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

   activity = getActivity();

    View rootView = inflater.inflate(R.layout.augmented_reality_view, container, false);

    ActionBar actionBar = ((ActionBarActivity) activity).getSupportActionBar();

    actionBar.hide();

    HeadTracker = (ToggleButton) rootView.findViewById(R.id.HeadTracker);

    Left_Image = (ImageView) rootView.findViewById(R.id.lefty);
    Right_Image = (ImageView) rootView.findViewById(R.id.righty);


    Bitmap icon = BitmapFactory.decodeResource(activity.getResources(),
            R.drawable.ytyty);

    BitmapDrawable Image = Rotate_Image(icon);

    Left_Image.setImageDrawable(Image);

    return rootView;
}


@Override
public void onSensorChanged(SensorEvent event) {

    if (HeadTracker.isChecked() == true) {

        if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {

            SensorManager.getRotationMatrixFromVector(
                    mRotationMatrix, event.values);

            if (mRotationMatrix[2] >= 0.6 && mRotationMatrix[0] >= -0.1 && mRotationMatrix[0] <= 0.2) {

                Left = true;
                Right = false;


            } else if (mRotationMatrix[2] <= -0.6 && mRotationMatrix[0] >= -0.1 && mRotationMatrix[0] <= 0.2) {

                Left = false;
                Right = true;


            } else {
                Left = false;
                Right = false;


            }

        }

    }

    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {

        if (event.values[2] >= 390) {
            MagnetButtonPressed = true;
        } else {
            MagnetButtonPressed = false;
        }

    }

}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

@Override
public void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(this);
}

public BitmapDrawable Rotate_Image(Bitmap Image) {

    Bitmap bitmapOrg = Image;

    int width = bitmapOrg.getWidth();
    int height = bitmapOrg.getHeight();

    Matrix matrix = new Matrix();

    matrix.postRotate(90);

    Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, width, height, matrix, true);

    BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);

    return bmd;

}

public void UpdateImages(Bitmap Image) {

    System.out.println("Image Updated");

    final BitmapDrawable Image_Rotated = Rotate_Image(Image);

    System.out.println("Is Added Result: " + isAdded());

    if(isAdded()) {
        System.out.println("Fragment Added");
        Left_Image.setImageDrawable(Image_Rotated);
        Right_Image.setImageDrawable(Image_Rotated);
    }


}

}

主要活动:

package com.example.jaynesh.mobile_robot_interface.Main_Files;

import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import com.example.jaynesh.mobile_robot_interface.Fragments.Augmented_Reality;
import com.example.jaynesh.mobile_robot_interface.Fragments.Main_Screen;
import com.example.jaynesh.mobile_robot_interface.Fragments.Settings;
import com.example.jaynesh.mobile_robot_interface.Fragments.Mission_Data;
import com.example.jaynesh.mobile_robot_interface.Navigation_Drawer.DrawerItemCustomAdapter;
import com.example.jaynesh.mobile_robot_interface.Navigation_Drawer.ObjectDrawerItem;
import com.example.jaynesh.mobile_robot_interface.Packets.Fragment_Tags.Augmented_Reality_Identifier;
import com.example.jaynesh.mobile_robot_interface.Packets.Fragment_Tags.Main_Screen_Identifier;
import com.example.jaynesh.mobile_robot_interface.Packets.Fragment_Tags.Mission_Data_Identifier;
import com.example.jaynesh.mobile_robot_interface.Packets.Fragment_Tags.Settings_Identifier;
import com.example.jaynesh.mobile_robot_interface.R;
import com.example.jaynesh.mobile_robot_interface.Socket.ClientThread;


public class MainActivity extends ActionBarActivity implements ClientThread.Image_Listener{

// declare properties
private String[] mNavigationDrawerItemTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;

private ActionBarDrawerToggle mDrawerToggle;

// nav drawer title
private CharSequence mDrawerTitle;

// used to store app title
private CharSequence mTitle;

public SharedPreferences sharedpreferences;
public static final String MyPREFERENCES = "MyPrefs" ;


ClientThread clientThread;

private Augmented_Reality Augmented_Reality_Fragment;
private Main_Screen Main_Screen_Fragment;
private Mission_Data Mission_Data_Fragment;
private Settings Settings_Fragment;

private boolean Socket_Connected = false;
private int Current_Page = 0;

Main_Screen_Identifier MS;
Augmented_Reality_Identifier AR;
Mission_Data_Identifier MD;
Settings_Identifier SF;

Thread serverThread = null;

boolean NewPage = false;



@Override
protected void onCreate(Bundle savedInstanceState) {

    MS = new Main_Screen_Identifier();
    AR = new Augmented_Reality_Identifier();
    MD = new Mission_Data_Identifier();
    SF = new Settings_Identifier();

    NewPage = true;

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    // for proper titles
    mTitle = mDrawerTitle = getTitle();

    // initialize properties
    mNavigationDrawerItemTitles = getResources().getStringArray(R.array.navigation_drawer_items_array);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);


    // list the drawer items
    ObjectDrawerItem[] drawerItem = new ObjectDrawerItem[4];

    drawerItem[0] = new ObjectDrawerItem(R.drawable.ic_action_share, "Main Screen");
    drawerItem[1] = new ObjectDrawerItem(R.drawable.ic_action_share, "Augment Reality View");
    drawerItem[2] = new ObjectDrawerItem(R.drawable.ic_action_share, "Mission Data");
    drawerItem[3] = new ObjectDrawerItem(R.drawable.ic_action_share, "Settings");

    // Pass the folderData to our ListView adapter
    DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.listview_item_row, drawerItem);

    // Set the adapter for the list view
    mDrawerList.setAdapter(adapter);

    // set the item click listener
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());


    // for app icon control for nav drawer
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerToggle = new ActionBarDrawerToggle(
            this,                  /* host Activity */
            mDrawerLayout,         /* DrawerLayout object */
            R.drawable.ic_drawer,  /* nav drawer icon to replace 'Up' caret */
            R.string.drawer_open,  /* "open drawer" description */
            R.string.drawer_close  /* "close drawer" description */
    ) {

        /** Called when a drawer has settled in a completely closed state. */
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
            getSupportActionBar().setTitle(mTitle);
        }

        /** Called when a drawer has settled in a completely open state. */
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            getSupportActionBar().setTitle(mDrawerTitle);
        }
    };

    // Set the drawer toggle as the DrawerListener
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    // enable ActionBar app icon to behave as action to toggle nav drawer
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);



    if (savedInstanceState == null) {
        // on first time display view for first nav item
        selectItem(0);
    }


}

@Override
public void OnNewImageListenerBitmap(final Bitmap Image) {


    if (Thread.currentThread().getName() == "main") {
        Augmented_Reality_Fragment.UpdateImages(Image);
    }
    MainActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (Augmented_Reality_Fragment != null) {

                Augmented_Reality_Fragment.UpdateImages(Image);
            }

        }
    });

}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {

    // The action bar home/up action should open or close the drawer.
    // ActionBarDrawerToggle will take care of this.
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}




// to change up caret
@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}


// navigation drawer click listener
private class DrawerItemClickListener implements ListView.OnItemClickListener {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }

}


private void selectItem(int position) {


    Fragment fragment = null;

    SharedPreferences.Editor editor = sharedpreferences.edit();

    switch (position) {
        case 0:
            editor.putBoolean("Image_Listener", false);
            editor.commit();
            if (Main_Screen_Fragment == null) {
                Main_Screen_Fragment = new Main_Screen();
            }
            fragment = Main_Screen_Fragment;

            Current_Page = 1;

            NewPage = true;

            break;
        case 1:
            editor.putBoolean("Image_Listener", true);
            editor.commit();
            if (Augmented_Reality_Fragment == null) {
                Augmented_Reality_Fragment = new Augmented_Reality();
            }
            fragment = new Augmented_Reality();

            Current_Page = 2;

            NewPage = true;

            break;
        case 2:
            editor.putBoolean("Image_Listener", false);
            editor.commit();
            if (Mission_Data_Fragment == null) {
                Mission_Data_Fragment = new Mission_Data();
            }
            fragment = Mission_Data_Fragment;

            Current_Page = 3;

            NewPage = true;

            break;
        case 3:
            editor.putBoolean("Image_Listener", false);
            editor.commit();
            if (Settings_Fragment == null) {
                Settings_Fragment = new Settings();
            }
            fragment = Settings_Fragment;

            Current_Page = 4;

            NewPage = true;

            break;

        default:
            break;
    }

    if (fragment != null) {
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(mNavigationDrawerItemTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);

    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }
}

@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getSupportActionBar().setTitle(mTitle);
}

@Override
public void onBackPressed() {
}

}

更新接口的线程:

if (Listener != null) {
                                    System.out.println("Listener Found");

                                    Image_data = BitmapFactory.decodeByteArray(tmp, 0, tmp.length);
                                    System.out.println("Image Created");
                                    Listener.OnNewImageListenerBitmap(Image_data);
                                    //sendMessage(Image_Flag.to_byte_array(Image_Sync_Flag));
                                    System.out.println("Updated");

                                }

我被这个问题困扰了一段时间,我不确定出了什么问题,任何帮助都会很棒 :)

史蒂夫

//////////.............\\\\\\

添加了崩溃日志

08-02 01:16:29.997  26346-26346/com.interface E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageDrawable(android.graphics.drawable.Drawable)' on a null object reference
        at com.example.jaynesh.mobile_robot_interface.Fragments.Augmented_Reality.UpdateImages(Augmented_Reality.java:215)
        at com.example.jaynesh.mobile_robot_interface.Main_Files.MainActivity.run(MainActivity.java:180)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

编辑:在您的 case 1 中,务必使用您之前设置的片段

您有:

        if (Augmented_Reality_Fragment == null) {
            Augmented_Reality_Fragment = new Augmented_Reality();
        }
        fragment = new Augmented_Reality();

你应该有:

        if (Augmented_Reality_Fragment == null) {
            Augmented_Reality_Fragment = new Augmented_Reality();
        }
        fragment = Augmented_Reality_Fragment;